@applicaster/zapp-react-native-ui-components 15.1.4 → 16.0.0-alpha.1042942411

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/Components/BackgroundImage/index.ts +1 -8
  2. package/Components/BaseFocusable/index.ios.ts +12 -2
  3. package/Components/Cell/FocusableWrapper.tsx +3 -0
  4. package/Components/Cell/TvOSCellComponent.tsx +6 -3
  5. package/Components/CellRendererResolver/index.ts +1 -1
  6. package/Components/Focusable/Focusable.tsx +4 -2
  7. package/Components/Focusable/FocusableTvOS.tsx +18 -1
  8. package/Components/Focusable/__tests__/__snapshots__/FocusableTvOS.test.tsx.snap +1 -0
  9. package/Components/FocusableGroup/FocusableTvOS.tsx +30 -1
  10. package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +39 -0
  11. package/Components/GeneralContentScreen/__tests__/GeneralContentScreenHookAdapter.test.tsx +64 -0
  12. package/Components/GeneralContentScreen/__tests__/HookContentFocusGroup.web.test.tsx +91 -0
  13. package/Components/GeneralContentScreen/hookAdapter/__tests__/networkService.test.ts +74 -0
  14. package/Components/GeneralContentScreen/hookAdapter/__tests__/runInBackground.test.ts +139 -0
  15. package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +124 -0
  16. package/Components/GeneralContentScreen/hookAdapter/logger.ts +6 -0
  17. package/Components/GeneralContentScreen/hookAdapter/networkService.ts +53 -0
  18. package/Components/GeneralContentScreen/hookAdapter/runInBackground.ts +48 -0
  19. package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +72 -0
  20. package/Components/GeneralContentScreen/hookFocus/index.tsx +13 -0
  21. package/Components/GeneralContentScreen/hookFocus/index.web.tsx +69 -0
  22. package/Components/GeneralContentScreen/index.ts +2 -0
  23. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +1 -1
  24. package/Components/HandlePlayable/HandlePlayable.tsx +13 -8
  25. package/Components/Layout/TV/NavBarContainer.tsx +1 -10
  26. package/Components/Layout/TV/ScreenContainer.tsx +2 -6
  27. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +7 -12
  28. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +7 -12
  29. package/Components/Layout/TV/index.tsx +3 -4
  30. package/Components/Layout/TV/index.web.tsx +3 -4
  31. package/Components/LinkHandler/LinkHandler.tsx +2 -2
  32. package/Components/MasterCell/CONFIG_BUILDER_TO_REACT_COMPONENT.md +144 -0
  33. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +27 -48
  34. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
  35. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +213 -0
  36. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
  37. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
  38. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +165 -0
  39. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +405 -0
  40. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/index.ts +1 -0
  41. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
  42. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +198 -0
  43. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
  44. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
  45. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
  46. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +217 -46
  47. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +50 -119
  48. package/Components/MasterCell/DefaultComponents/Button.tsx +50 -58
  49. package/Components/MasterCell/DefaultComponents/ButtonContainerView/components/HorizontalSeparator.tsx +8 -0
  50. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.android.tv.tsx +58 -0
  51. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.tsx +15 -0
  52. package/Components/MasterCell/DefaultComponents/{tv/ButtonContainerView/index.tsx → ButtonContainerView/index.tv.tsx} +3 -11
  53. package/Components/MasterCell/DefaultComponents/ButtonContainerView/index.web.ts +1 -0
  54. package/Components/MasterCell/DefaultComponents/ButtonContainerView/types.ts +40 -0
  55. package/Components/MasterCell/DefaultComponents/CellBadge/__tests__/__snapshots__/index.test.tsx.snap +18 -0
  56. package/Components/MasterCell/DefaultComponents/CellBadge/__tests__/index.test.tsx +90 -0
  57. package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +13 -14
  58. package/Components/MasterCell/DefaultComponents/DataProvider/index.tsx +163 -0
  59. package/Components/MasterCell/DefaultComponents/FocusableView/index.android.tsx +2 -23
  60. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -22
  61. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +8 -2
  62. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +11 -3
  63. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +9 -1
  64. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +15 -14
  65. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -3
  66. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +1 -2
  67. package/Components/MasterCell/DefaultComponents/PressableView.tsx +54 -0
  68. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +46 -50
  69. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +47 -39
  70. package/Components/MasterCell/DefaultComponents/SecondaryImage/hooks/__tests__/useGetImageDimensions.test.ts +7 -6
  71. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +19 -6
  72. package/Components/MasterCell/DefaultComponents/Text/hooks/useText.ts +15 -0
  73. package/Components/MasterCell/DefaultComponents/Text/index.tsx +45 -15
  74. package/Components/MasterCell/DefaultComponents/UIKitAdapters/Badge.tsx +49 -0
  75. package/Components/MasterCell/DefaultComponents/__tests__/ActionButton.test.tsx +122 -0
  76. package/Components/MasterCell/DefaultComponents/__tests__/Button.test.tsx +186 -0
  77. package/Components/MasterCell/DefaultComponents/__tests__/DataProvider.test.tsx +141 -0
  78. package/Components/MasterCell/DefaultComponents/__tests__/DynamicBadge.test.tsx +156 -0
  79. package/Components/MasterCell/DefaultComponents/__tests__/__snapshots__/ActionButton.test.tsx.snap +60 -0
  80. package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +196 -67
  81. package/Components/MasterCell/DefaultComponents/index.ts +13 -3
  82. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +189 -0
  83. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +33 -0
  84. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +33 -0
  85. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +159 -0
  86. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +18 -0
  87. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
  88. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +39 -0
  89. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +402 -0
  90. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +141 -0
  91. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +354 -0
  92. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
  93. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +129 -0
  94. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +123 -0
  95. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +238 -0
  96. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/Asset.ts +4 -18
  97. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/Button.ts +24 -73
  98. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/TextLabelsContainer.ts +37 -18
  99. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/TvActionButton.tsx +27 -0
  100. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +89 -0
  101. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/renderedTree.test.tsx +231 -0
  102. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +47 -48
  103. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +115 -29
  104. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/insertButtonsBetweenLabels.test.ts +45 -13
  105. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +101 -144
  106. package/Components/MasterCell/MappingFunctions/index.js +3 -2
  107. package/Components/MasterCell/README.md +4 -0
  108. package/Components/MasterCell/__tests__/__snapshots__/dataAdapter.test.js.snap +24 -0
  109. package/Components/MasterCell/__tests__/configInflater.test.js +1 -0
  110. package/Components/MasterCell/__tests__/elementMapper.test.js +46 -0
  111. package/Components/MasterCell/contexts/PressedStateContext.ts +3 -0
  112. package/Components/MasterCell/dataAdapter.ts +4 -1
  113. package/Components/MasterCell/elementMapper.tsx +54 -7
  114. package/Components/MasterCell/hooks/index.ts +2 -0
  115. package/Components/MasterCell/hooks/usePressedState.ts +4 -0
  116. package/Components/MasterCell/index.tsx +20 -4
  117. package/Components/MasterCell/utils/__tests__/cloneChildrenWithIds.test.tsx +43 -0
  118. package/Components/MasterCell/utils/__tests__/useFilterChildren.test.tsx +80 -0
  119. package/Components/MasterCell/utils/index.ts +82 -16
  120. package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +33 -69
  121. package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +25 -47
  122. package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +122 -39
  123. package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +671 -0
  124. package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +257 -88
  125. package/Components/ModalComponent/AudioPlayer/Components/index.ts +6 -4
  126. package/Components/ModalComponent/BottomSheetDragArea.tsx +33 -0
  127. package/Components/ModalComponent/BottomSheetModalContent.tsx +17 -10
  128. package/Components/ModalComponent/__tests__/BottomSheetDragArea.test.tsx +74 -0
  129. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +4 -85
  130. package/Components/OfflineHandler/__tests__/index.test.tsx +101 -32
  131. package/Components/OfflineHandler/hooks.ts +123 -0
  132. package/Components/OfflineHandler/index.tsx +51 -73
  133. package/Components/OfflineHandler/utils/index.ts +1 -13
  134. package/Components/PlayerContainer/PlayerContainer.tsx +6 -5
  135. package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +2 -4
  136. package/Components/PreloaderWrapper/index.tsx +1 -1
  137. package/Components/River/ComponentsMap/ComponentsMap.tsx +8 -21
  138. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +1 -1
  139. package/Components/River/RefreshControl.tsx +19 -105
  140. package/Components/River/River.tsx +9 -82
  141. package/Components/River/TV/River.tsx +31 -14
  142. package/Components/River/TV/index.tsx +8 -4
  143. package/Components/River/TV/utils/__tests__/toStringOrEmpty.test.ts +30 -0
  144. package/Components/River/TV/utils/index.ts +4 -0
  145. package/Components/River/TV/withFocusableGroupForContent.tsx +71 -0
  146. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +4 -0
  147. package/Components/River/__tests__/componentsMap.test.js +38 -0
  148. package/Components/River/hooks/__tests__/usePullToRefresh.test.ts +132 -0
  149. package/Components/River/hooks/index.ts +1 -0
  150. package/Components/River/hooks/usePullToRefresh.ts +51 -0
  151. package/Components/Screen/TV/index.web.tsx +4 -2
  152. package/Components/Screen/__tests__/Screen.test.tsx +65 -42
  153. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +68 -44
  154. package/Components/Screen/hooks.ts +2 -3
  155. package/Components/Screen/index.tsx +2 -3
  156. package/Components/Screen/orientationHandler.ts +3 -3
  157. package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +5 -3
  158. package/Components/ScreenResolver/index.tsx +9 -5
  159. package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +1 -1
  160. package/Components/ScreenRevealManager/ScreenRevealManager.ts +40 -8
  161. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +86 -69
  162. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +1 -1
  163. package/Components/Tabs/TabContent.tsx +7 -4
  164. package/Components/TopCutoffOverlay/__tests__/TopCutoffOverlay.test.tsx +201 -0
  165. package/Components/TopCutoffOverlay/hooks/__tests__/useMarginTop.test.ts +130 -0
  166. package/Components/TopCutoffOverlay/hooks/index.ts +1 -0
  167. package/Components/TopCutoffOverlay/hooks/useMarginTop.ts +59 -0
  168. package/Components/TopCutoffOverlay/index.tsx +55 -0
  169. package/Components/Transitioner/index.js +3 -3
  170. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +5 -5
  171. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +15 -7
  172. package/Components/VideoModal/utils.ts +12 -10
  173. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +0 -2
  174. package/Components/Viewport/ViewportAware/index.tsx +16 -7
  175. package/Components/Viewport/ViewportEvents/__tests__/viewportEvents.test.js +1 -1
  176. package/Components/default-cell-renderer/viewTrees/mobile/index.ts +0 -3
  177. package/Contexts/CachedDimensionsContext/__tests__/index.test.ts +154 -0
  178. package/Contexts/ScreenContext/index.tsx +25 -18
  179. package/Contexts/ScreenTrackedViewPositionsContext/__tests__/index.test.tsx +1 -1
  180. package/Decorators/Analytics/index.tsx +6 -5
  181. package/Decorators/ConfigurationWrapper/__tests__/__snapshots__/withConfigurationProvider.test.tsx.snap +1 -0
  182. package/Decorators/ConfigurationWrapper/const.ts +1 -0
  183. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +39 -21
  184. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +1 -1
  185. package/Decorators/ZappPipesDataConnector/index.tsx +2 -2
  186. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +1 -1
  187. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +18 -7
  188. package/Helpers/DataSourceHelper/__tests__/itemLimitForData.test.ts +80 -0
  189. package/Helpers/DataSourceHelper/index.ts +19 -0
  190. package/package.json +5 -5
  191. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +0 -135
  192. package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/types.ts +0 -25
  193. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +0 -112
  194. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +0 -107
  195. package/Components/OfflineHandler/NotificationView/NotificationView.tsx +0 -153
  196. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -67
  197. package/Components/OfflineHandler/NotificationView/utils.ts +0 -34
  198. package/Components/River/TV/withTVEventHandler.tsx +0 -36
  199. package/Helpers/DataSourceHelper/index.js +0 -19
  200. /package/Components/BackgroundImage/{BackgroundImage.tv.android.tsx → BackgroundImage.android.tv.tsx} +0 -0
  201. /package/Components/BackgroundImage/{BackgroundImage.tv.ios.tsx → BackgroundImage.ios.tv.tsx} +0 -0
  202. /package/Components/BackgroundImage/{BackgroundImage.tv.web.tsx → BackgroundImage.tsx} +0 -0
@@ -1,53 +1,123 @@
1
- import { getPluginIdentifier } from "..";
1
+ import { getPluginIdentifier, memoizedGetPluginIdentifier } from "..";
2
2
 
3
3
  describe("getPluginIdentifier", () => {
4
4
  const prefix = "tv_buttons";
5
5
 
6
- it("get first plugin identifier", () => {
6
+ beforeAll(() => {
7
+ memoizedGetPluginIdentifier.clear();
8
+ });
9
+
10
+ it("returns the requested slot action identifier", () => {
11
+ expect.assertions(2);
12
+
7
13
  const configuration = {
8
- tv_buttons_button_1_other: "value",
9
14
  tv_buttons_button_1_assign_action:
10
15
  "tv_buttons_button_1_assign_action_value",
11
- tv_buttons_button_2_assign_action:
12
- "tv_buttons_button_2_assign_action_value",
16
+ tv_buttons_button_3_assign_action:
17
+ "tv_buttons_button_3_assign_action_value",
13
18
  };
14
19
 
15
- const index = 0;
20
+ const slot = 3;
21
+ const result = getPluginIdentifier(configuration, prefix, slot);
16
22
 
17
- const result = getPluginIdentifier(configuration, prefix, index);
23
+ const memoizedResult = memoizedGetPluginIdentifier(
24
+ configuration,
25
+ prefix,
26
+ slot
27
+ );
18
28
 
19
- expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
29
+ expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
30
+ expect(memoizedResult).toEqual(result);
20
31
  });
21
32
 
22
- it("get second plugin identifier", () => {
33
+ it("returns undefined for a disabled or missing slot", () => {
34
+ expect.assertions(2);
35
+
23
36
  const configuration = {
24
- tv_buttons_button_1_other: "value_1",
25
- tv_buttons_button_1_assign_action:
26
- "tv_buttons_button_1_assign_action_value",
27
- tv_buttons_button_2_other: "value_2",
28
- tv_buttons_button_2_assign_action:
29
- "tv_buttons_button_2_assign_action_value",
37
+ tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
30
38
  };
31
39
 
32
- const index = 1;
40
+ const slot = 2;
41
+ const result = getPluginIdentifier(configuration, prefix, slot);
33
42
 
34
- const result = getPluginIdentifier(configuration, prefix, index);
43
+ const memoizedResult = memoizedGetPluginIdentifier(
44
+ configuration,
45
+ prefix,
46
+ slot
47
+ );
35
48
 
36
- expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
49
+ expect(result).toBeUndefined();
50
+ expect(memoizedResult).toEqual(result);
51
+ });
52
+
53
+ it("returns undefined for empty string values", () => {
54
+ expect.assertions(2);
55
+
56
+ const configuration = {
57
+ tv_buttons_button_2_assign_action: "",
58
+ };
59
+
60
+ const slot = 2;
61
+
62
+ const result = getPluginIdentifier(configuration, prefix, slot);
63
+
64
+ const memoizedResult = memoizedGetPluginIdentifier(
65
+ configuration,
66
+ prefix,
67
+ slot
68
+ );
69
+
70
+ expect(result).toBeUndefined();
71
+ expect(memoizedResult).toBeUndefined();
37
72
  });
38
73
 
39
- it("get undefined if no assign_actions at all", () => {
40
- const configuration = {};
74
+ it("returns undefined for negative slots", () => {
75
+ expect.assertions(2);
76
+
77
+ const configuration = {
78
+ tv_buttons_button_1_assign_action: "a",
79
+ tv_buttons_button_2_assign_action: "b",
80
+ };
41
81
 
42
- const index = 0;
82
+ const slot = -1;
83
+ const result = getPluginIdentifier(configuration, prefix, slot);
43
84
 
44
- const result = getPluginIdentifier(configuration, prefix, index);
85
+ const memoizedResult = memoizedGetPluginIdentifier(
86
+ configuration,
87
+ prefix,
88
+ slot
89
+ );
45
90
 
46
91
  expect(result).toBeUndefined();
92
+ expect(memoizedResult).toBeUndefined();
93
+ });
94
+
95
+ it("handles non-string values by returning the configured slot value", () => {
96
+ expect.assertions(2);
97
+
98
+ const configuration = {
99
+ tv_buttons_button_2_assign_action: true,
100
+ };
101
+
102
+ const slot = 2;
103
+ const result = getPluginIdentifier(configuration, prefix, slot);
104
+
105
+ const memoizedResult = memoizedGetPluginIdentifier(
106
+ configuration,
107
+ prefix,
108
+ slot
109
+ );
110
+
111
+ expect(result).toBe(true);
112
+ expect(memoizedResult).toBe(true);
47
113
  });
48
114
  });
49
115
 
50
- describe("getPluginIdentifier - when configuration has same values for different keys", () => {
116
+ describe("getPluginIdentifier - when configuration has duplicate values", () => {
117
+ beforeAll(() => {
118
+ memoizedGetPluginIdentifier.clear();
119
+ });
120
+
51
121
  const prefix = "tv_buttons";
52
122
 
53
123
  const configuration = {
@@ -55,19 +125,35 @@ describe("getPluginIdentifier - when configuration has same values for different
55
125
  tv_buttons_button_2_assign_action: "navigation_action",
56
126
  };
57
127
 
58
- it("get first plugin identifier", () => {
59
- const index = 0;
128
+ it("returns the requested slot even when values are identical", () => {
129
+ expect.assertions(2);
60
130
 
61
- const result = getPluginIdentifier(configuration, prefix, index);
131
+ const slot = 1;
132
+ const result = getPluginIdentifier(configuration, prefix, slot);
133
+
134
+ const memoizedResult = memoizedGetPluginIdentifier(
135
+ configuration,
136
+ prefix,
137
+ slot
138
+ );
62
139
 
63
140
  expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
141
+ expect(memoizedResult).toEqual(result);
64
142
  });
65
143
 
66
- it("get second plugin identifier", () => {
67
- const index = 1;
144
+ it("returns the second slot when values are identical", () => {
145
+ expect.assertions(2);
146
+
147
+ const slot = 2;
148
+ const result = getPluginIdentifier(configuration, prefix, slot);
68
149
 
69
- const result = getPluginIdentifier(configuration, prefix, index);
150
+ const memoizedResult = memoizedGetPluginIdentifier(
151
+ configuration,
152
+ prefix,
153
+ slot
154
+ );
70
155
 
71
156
  expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
157
+ expect(memoizedResult).toEqual(result);
72
158
  });
73
159
  });
@@ -3,18 +3,20 @@ import { insertButtonsBetweenLabels } from "..";
3
3
  describe("insertButtonsBetweenLabels - depthlevel 1", () => {
4
4
  const buttons = "buttons";
5
5
 
6
- const labels = [
7
- { name: "label_1" },
8
- { name: "label_2" },
9
- { name: "label_3" },
6
+ const slots = [
7
+ { name: "label_1", element: { id: "label_1" } },
8
+ { name: "label_2", element: { id: "label_2" } },
9
+ { name: "label_3", element: { id: "label_3" } },
10
10
  ];
11
11
 
12
+ const labels = slots.map((slot) => slot.element);
13
+
12
14
  it("put buttons on top", () => {
13
15
  const configuration = {
14
16
  tv_buttons_container_position: "on_top",
15
17
  };
16
18
 
17
- const result = insertButtonsBetweenLabels(configuration, buttons, labels);
19
+ const result = insertButtonsBetweenLabels(configuration, buttons, slots);
18
20
 
19
21
  expect(result).toEqual([buttons, ...labels]);
20
22
  });
@@ -24,7 +26,7 @@ describe("insertButtonsBetweenLabels - depthlevel 1", () => {
24
26
  tv_buttons_container_position: "unknown_position",
25
27
  };
26
28
 
27
- const result = insertButtonsBetweenLabels(configuration, buttons, labels);
29
+ const result = insertButtonsBetweenLabels(configuration, buttons, slots);
28
30
 
29
31
  expect(result).toEqual([...labels, buttons]);
30
32
  });
@@ -34,7 +36,7 @@ describe("insertButtonsBetweenLabels - depthlevel 1", () => {
34
36
  tv_buttons_container_position: "label_1",
35
37
  };
36
38
 
37
- const result = insertButtonsBetweenLabels(configuration, buttons, labels);
39
+ const result = insertButtonsBetweenLabels(configuration, buttons, slots);
38
40
 
39
41
  expect(result).toEqual([labels[0], buttons, labels[1], labels[2]]);
40
42
  });
@@ -44,7 +46,7 @@ describe("insertButtonsBetweenLabels - depthlevel 1", () => {
44
46
  tv_buttons_container_position: "label_2",
45
47
  };
46
48
 
47
- const result = insertButtonsBetweenLabels(configuration, buttons, labels);
49
+ const result = insertButtonsBetweenLabels(configuration, buttons, slots);
48
50
 
49
51
  expect(result).toEqual([labels[0], labels[1], buttons, labels[2]]);
50
52
  });
@@ -54,22 +56,52 @@ describe("insertButtonsBetweenLabels - depthlevel 1", () => {
54
56
  tv_buttons_container_position: "label_3",
55
57
  };
56
58
 
57
- const result = insertButtonsBetweenLabels(configuration, buttons, labels);
59
+ const result = insertButtonsBetweenLabels(configuration, buttons, slots);
58
60
 
59
61
  expect(result).toEqual([labels[0], labels[1], labels[2], buttons]);
60
62
  });
61
63
 
62
- it("put underneath all", () => {
64
+ it("put above label_2", () => {
65
+ const configuration = {
66
+ tv_buttons_container_position: "above_label_2",
67
+ };
68
+
69
+ const result = insertButtonsBetweenLabels(configuration, buttons, slots);
70
+
71
+ expect(result).toEqual([labels[0], buttons, labels[1], labels[2]]);
72
+ });
73
+
74
+ it("keeps the slot when its label is empty (null element)", () => {
75
+ const slotsWithEmpty = [
76
+ { name: "label_1", element: { id: "label_1" } },
77
+ { name: "label_2", element: null },
78
+ { name: "label_3", element: { id: "label_3" } },
79
+ ];
80
+
81
+ const configuration = {
82
+ tv_buttons_container_position: "above_label_2",
83
+ };
84
+
85
+ const result = insertButtonsBetweenLabels(
86
+ configuration,
87
+ buttons,
88
+ slotsWithEmpty
89
+ );
90
+
91
+ expect(result).toEqual([{ id: "label_1" }, buttons, { id: "label_3" }]);
92
+ });
93
+
94
+ it("appends buttons when the target is unknown", () => {
63
95
  const configuration = {
64
96
  tv_buttons_container_position: "label_X",
65
97
  };
66
98
 
67
- const result = insertButtonsBetweenLabels(configuration, buttons, labels);
99
+ const result = insertButtonsBetweenLabels(configuration, buttons, slots);
68
100
 
69
101
  expect(result).toEqual([labels[0], labels[1], labels[2], buttons]);
70
102
  });
71
103
 
72
- it("put underneath all", () => {
104
+ it("appends buttons when there are no slots", () => {
73
105
  const configuration = {
74
106
  tv_buttons_container_position: "label_X",
75
107
  };
@@ -88,7 +120,7 @@ describe("insertButtonsBetweenLabels - depthlevel 1", () => {
88
120
  tv_buttons_container_position: "label_X",
89
121
  };
90
122
 
91
- const result = insertButtonsBetweenLabels(configuration, null, labels);
123
+ const result = insertButtonsBetweenLabels(configuration, null, slots);
92
124
 
93
125
  expect(result).toEqual(labels);
94
126
  });
@@ -1,173 +1,72 @@
1
- import * as R from "ramda";
2
-
1
+ import memoizee from "memoizee";
3
2
  import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
4
- import { isNotNil } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
3
+ import {
4
+ toNumberWithDefault,
5
+ toNumberWithDefaultZero,
6
+ } from "@applicaster/zapp-react-native-utils/numberUtils";
7
+ import { getEnabledButtonSlots } from "../../../ActionButtonsCore/selectors";
8
+ import {
9
+ insertBetweenLabelContainers,
10
+ insertBetweenLabels,
11
+ } from "../../../ActionButtonsCore/placement";
5
12
 
6
13
  export const getButtonsCount = (
7
14
  configuration: Record<string, unknown>,
8
15
  prefix: string
9
16
  ): number => {
10
- const button1Key = `${prefix}_button_1_button_enabled`;
11
- const button2Key = `${prefix}_button_2_button_enabled`;
12
- const button3Key = `${prefix}_button_3_button_enabled`;
13
-
14
- return R.toPairs(configuration).filter(
15
- ([key, value]) =>
16
- [button1Key, button2Key, button3Key].includes(key) && value
17
- ).length;
17
+ return getEnabledButtonSlots(configuration, `${prefix}_button`).length;
18
18
  };
19
19
 
20
20
  export const getPluginIdentifier = (
21
21
  configuration: Record<string, unknown>,
22
22
  prefix: string,
23
- index: number
24
- ): string => {
25
- const match = `${prefix}_button_\\d_assign_action`;
26
- const re = new RegExp(match);
27
-
28
- const rejectNils = R.compose(R.path([index]), R.filter(isNotNil));
29
-
30
- return rejectNils(
31
- R.toPairs(configuration)
32
- .filter(([key]) => R.startsWith(`${prefix}_button`, key))
33
- .map(([key, value]) => {
34
- const matched = key.match(re);
35
-
36
- return matched ? value : undefined;
37
- })
38
- );
39
- };
40
-
41
- type Label = {
42
- name: string;
43
- };
44
-
45
- type LabelContainer = {
46
- elements: Array<Label>;
47
- };
48
-
49
- type LabelExtraContainer = {
50
- elements: Array<LabelContainer>;
51
- };
52
-
53
- const withButtons = (labelName, buttons, labels) => {
54
- return labels.reduce((acc, label) => {
55
- if (label.name === labelName) {
56
- return [...acc, label, buttons];
57
- }
23
+ slot: number
24
+ ): string | undefined => {
25
+ const value = configuration[
26
+ `${prefix}_button_${slot}_assign_action`
27
+ ] as string;
58
28
 
59
- return [...acc, label];
60
- }, []);
29
+ return value == null || value === "" ? undefined : value;
61
30
  };
62
31
 
63
- const withButtonsInContainer = (labelName, buttons, views) => {
64
- return views.map((view) => {
65
- return {
66
- ...view,
67
- elements: view.elements.reduce((acc, label) => {
68
- if (label.name === labelName) {
69
- return [...acc, label, buttons];
70
- }
71
-
72
- return [...acc, label];
73
- }, []),
74
- };
75
- });
76
- };
32
+ export const memoizedGetPluginIdentifier = memoizee(getPluginIdentifier);
77
33
 
78
34
  export const insertButtonsBetweenLabels = (
79
35
  configuration: Record<string, unknown>,
80
36
  buttons,
81
- labels: Label[] = []
82
- ) => {
83
- if (R.isNil(buttons)) {
84
- return labels;
85
- }
86
-
87
- const position = R.pathOr(
88
- undefined,
89
- ["tv_buttons_container_position"],
90
- configuration
37
+ slots = [] // { name, element } per canonical text label slot
38
+ ) =>
39
+ insertBetweenLabels(
40
+ {
41
+ position: configuration.tv_buttons_container_position as
42
+ | string
43
+ | undefined,
44
+ allowOnTop: true,
45
+ appendWhenMissing: true,
46
+ },
47
+ buttons,
48
+ slots
91
49
  );
92
50
 
93
- if (position === "on_top") {
94
- return [buttons, ...labels];
95
- }
96
-
97
- const labelsWithButtons = withButtons(position, buttons, labels);
98
-
99
- if (R.equals(labelsWithButtons, labels)) {
100
- // put buttons after all labels by default
101
- return [...labels, buttons];
102
- }
103
-
104
- return labelsWithButtons;
105
- };
106
-
107
51
  export const insertButtonsBetweenLabelContainers = (
108
52
  configuration: Record<string, unknown>,
109
53
  buttons,
110
- labelContainers: Array<LabelExtraContainer> = []
111
- ) => {
112
- if (R.isNil(buttons)) {
113
- return labelContainers;
114
- }
115
-
116
- if (R.isEmpty(labelContainers)) {
117
- return [buttons];
118
- }
119
-
120
- const position = R.pathOr(
121
- undefined,
122
- ["tv_buttons_container_position"],
123
- configuration
54
+ labelContainers = []
55
+ ) =>
56
+ insertBetweenLabelContainers(
57
+ {
58
+ position: configuration.tv_buttons_container_position as
59
+ | string
60
+ | undefined,
61
+ allowOnTop: true,
62
+ appendWhenMissing: true,
63
+ },
64
+ buttons,
65
+ labelContainers
124
66
  );
125
67
 
126
- if (position === "on_top") {
127
- const firstContainerLabels = R.lensPath([0, "elements"]);
128
-
129
- return R.over(firstContainerLabels, R.prepend(buttons), labelContainers);
130
- }
131
-
132
- const labelContainersWithButtons = labelContainers.map((labelContainer) => {
133
- return {
134
- ...labelContainer,
135
- elements: withButtonsInContainer(
136
- position,
137
- buttons,
138
- labelContainer.elements
139
- ),
140
- };
141
- });
142
-
143
- if (R.equals(labelContainersWithButtons, labelContainers)) {
144
- // put buttons in last container
145
- const lastContainerLabels = R.lensPath([
146
- labelContainers.length - 1,
147
- "elements",
148
- ]);
149
-
150
- return R.over(lastContainerLabels, R.append(buttons), labelContainers);
151
- }
152
-
153
- return labelContainersWithButtons;
154
- };
155
-
156
- export const mapSelfAlignment = (horizontalPosition) => {
157
- switch (horizontalPosition) {
158
- case "left":
159
- return "flex-start";
160
- case "right":
161
- return "flex-end";
162
- case "center":
163
- return "center";
164
- default:
165
- return "flex-start";
166
- }
167
- };
168
-
169
68
  export const getTextTransform = (textTransform: string) => {
170
- if (R.isNil(textTransform) || R.isEmpty(textTransform)) {
69
+ if (textTransform == null || textTransform === "") {
171
70
  return "none";
172
71
  }
173
72
 
@@ -188,3 +87,61 @@ export const withAntialiasing = () => {
188
87
 
189
88
  return {};
190
89
  };
90
+
91
+ export const getMarginStyles = (value) => ({
92
+ marginTop: toNumberWithDefaultZero(value("margin_top")),
93
+ marginRight: toNumberWithDefaultZero(value("margin_right")),
94
+ marginBottom: toNumberWithDefaultZero(value("margin_bottom")),
95
+ marginLeft: toNumberWithDefaultZero(value("margin_left")),
96
+ });
97
+
98
+ export const getPaddingStyles = (value) => ({
99
+ paddingTop: toNumberWithDefaultZero(value("padding_top")),
100
+ paddingRight: toNumberWithDefaultZero(value("padding_right")),
101
+ paddingBottom: toNumberWithDefaultZero(value("padding_bottom")),
102
+ paddingLeft: toNumberWithDefaultZero(value("padding_left")),
103
+ });
104
+
105
+ export const getBorderStyles = (value) => ({
106
+ borderRadius: toNumberWithDefaultZero(value("corner_radius")),
107
+ borderWidth: toNumberWithDefaultZero(value("border_thickness")),
108
+ borderStyle: "solid",
109
+ borderColor: value("border_color"),
110
+ });
111
+
112
+ export const getAssetStyles = (value) => ({
113
+ ...getMarginStyles(value),
114
+ width: toNumberWithDefault(40, value("width")),
115
+ height: toNumberWithDefault(40, value("height")),
116
+ });
117
+
118
+ export const getTextLabelStyles = (value, platformValue) => ({
119
+ ...getMarginStyles(value),
120
+ ...getPaddingStyles(value),
121
+ borderRadius: toNumberWithDefaultZero(value("corner_radius")),
122
+ textAlign: value("text_alignment"),
123
+ textTransform: getTextTransform(value("text_transform")),
124
+ lineHeight: platformValue("line_height"),
125
+ letterSpacing: platformValue("letter_spacing"),
126
+ fontSize: platformValue("font_size"),
127
+ fontFamily: platformValue("font_family"),
128
+ ...withAntialiasing(),
129
+ });
130
+
131
+ export const getDisplayModeStyles = (value) => {
132
+ const mode = value("display_mode") || "dynamic";
133
+ const width = toNumberWithDefault(240, value("fixed_and_fixed_center_width"));
134
+
135
+ if (mode === "fixed") {
136
+ return { width };
137
+ }
138
+
139
+ if (mode === "fixed_center") {
140
+ return {
141
+ width,
142
+ justifyContent: "center",
143
+ };
144
+ }
145
+
146
+ return {};
147
+ };
@@ -1,7 +1,7 @@
1
- import * as R from "ramda";
2
1
  import { isDateValid } from "./Utils";
3
2
  import { masterCellLogger } from "../logger";
4
3
  import { imageSrcFromMediaItem as imageSrcFromMediaItemConfigUtils } from "@applicaster/zapp-react-native-utils/configurationUtils";
4
+ import { pathOr, identity } from "@applicaster/zapp-react-native-utils/utils";
5
5
 
6
6
  export const imageSrcFromMediaItem = (...args) => {
7
7
  __DEV__ &&
@@ -34,11 +34,12 @@ export function stringifyDateFromPath(obj, path) {
34
34
  * @returns {any} Found object or empty string
35
35
  */
36
36
  export function pathWithFallback(obj, path) {
37
- return R.pathOr("", path)(obj);
37
+ return pathOr("", path, obj);
38
38
  }
39
39
 
40
40
  // prettier-ignore
41
41
  const functionsNames = {
42
+ "identity": identity,
42
43
  "path": pathWithFallback,
43
44
  "image_src_from_media_item": imageSrcFromMediaItemConfigUtils,
44
45
  "stringify_date_from_path": stringifyDateFromPath,
@@ -1,5 +1,9 @@
1
1
  # MasterCell
2
2
 
3
+ ## Guides
4
+
5
+ - [Config Builder -> React Component Migration](./CONFIG_BUILDER_TO_REACT_COMPONENT.md)
6
+
3
7
  ## How to use it
4
8
 
5
9
  ```javascript