@applicaster/zapp-react-native-utils 13.0.0-rc.99 → 14.0.0-alpha.1235043154

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 (77) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +55 -6
  2. package/actionsExecutor/consts.ts +4 -0
  3. package/analyticsUtils/AnalyticsEvents/sendHeaderClickEvent.ts +1 -1
  4. package/analyticsUtils/AnalyticsEvents/sendMenuClickEvent.ts +2 -1
  5. package/analyticsUtils/index.tsx +3 -4
  6. package/analyticsUtils/manager.ts +1 -1
  7. package/appUtils/__tests__/__snapshots__/localizationsHelper.test.ts.snap +151 -0
  8. package/appUtils/__tests__/allZappLocales.ts +79 -0
  9. package/appUtils/__tests__/{localizationsHelper.test.js → localizationsHelper.test.ts} +11 -0
  10. package/appUtils/accessibilityManager/const.ts +18 -0
  11. package/appUtils/accessibilityManager/index.ts +4 -1
  12. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +1 -0
  13. package/appUtils/focusManager/index.ios.ts +14 -4
  14. package/appUtils/focusManager/utils/__tests__/findChild.test.ts +35 -0
  15. package/appUtils/focusManager/utils/index.ts +5 -0
  16. package/appUtils/localizationsHelper.ts +10 -2
  17. package/appUtils/playerManager/playerHooks/usePlayerCurrentTime.tsx +11 -7
  18. package/arrayUtils/__tests__/isEmptyArray.test.ts +63 -0
  19. package/arrayUtils/__tests__/isFilledArray.test.ts +1 -1
  20. package/arrayUtils/index.ts +7 -2
  21. package/audioPlayerUtils/__tests__/getArtworkImage.test.ts +144 -0
  22. package/audioPlayerUtils/__tests__/getBackgroundImage.test.ts +72 -0
  23. package/audioPlayerUtils/__tests__/getImageFromEntry.test.ts +110 -0
  24. package/audioPlayerUtils/assets/index.ts +2 -0
  25. package/audioPlayerUtils/index.ts +242 -0
  26. package/cellUtils/index.ts +9 -5
  27. package/componentsUtils/index.ts +8 -1
  28. package/conf/player/__tests__/selectors.test.ts +34 -0
  29. package/conf/player/selectors.ts +10 -0
  30. package/configurationUtils/__tests__/configurationUtils.test.js +0 -31
  31. package/configurationUtils/__tests__/getMediaItems.test.ts +65 -0
  32. package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +34 -0
  33. package/configurationUtils/index.ts +63 -34
  34. package/localizationUtils/index.ts +3 -3
  35. package/manifestUtils/_internals/getDefaultConfiguration.js +28 -0
  36. package/manifestUtils/{_internals.js → _internals/index.js} +2 -25
  37. package/manifestUtils/createConfig.js +4 -1
  38. package/manifestUtils/defaultManifestConfigurations/generalContent.js +13 -0
  39. package/manifestUtils/defaultManifestConfigurations/player.js +1228 -205
  40. package/manifestUtils/index.js +2 -0
  41. package/manifestUtils/keys.js +27 -2
  42. package/manifestUtils/progressBar/__tests__/mobileProgressBar.test.js +0 -30
  43. package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +1 -2
  44. package/navigationUtils/__tests__/navigationUtils.test.js +0 -65
  45. package/navigationUtils/index.ts +0 -31
  46. package/package.json +2 -2
  47. package/playerUtils/__tests__/configurationUtils.test.ts +1 -65
  48. package/playerUtils/__tests__/getPlayerActionButtons.test.ts +54 -0
  49. package/playerUtils/_internals/__tests__/utils.test.ts +71 -0
  50. package/playerUtils/_internals/index.ts +1 -0
  51. package/playerUtils/_internals/utils.ts +31 -0
  52. package/playerUtils/configurationUtils.ts +0 -44
  53. package/playerUtils/getPlayerActionButtons.ts +17 -0
  54. package/playerUtils/index.ts +25 -0
  55. package/playerUtils/useValidatePlayerConfig.tsx +22 -19
  56. package/reactHooks/app/useAppState.ts +2 -2
  57. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +12 -13
  58. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +39 -88
  59. package/reactHooks/feed/useBatchLoading.ts +12 -14
  60. package/reactHooks/navigation/{useGetTabBarHeight.ts → getTabBarHeight.ts} +1 -1
  61. package/reactHooks/navigation/index.ts +2 -2
  62. package/reactHooks/navigation/useGetBottomTabBarHeight.ts +10 -3
  63. package/reactHooks/navigation/useNavigationPluginData.ts +8 -4
  64. package/reactHooks/navigation/useNavigationType.ts +4 -2
  65. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +69 -0
  66. package/reactHooks/screen/useScreenBackgroundColor.ts +3 -15
  67. package/reactHooks/state/README.md +79 -0
  68. package/reactHooks/state/ZStoreProvider.tsx +71 -0
  69. package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +66 -0
  70. package/reactHooks/state/index.ts +2 -0
  71. package/reactHooks/useListenEventBusEvent.ts +1 -1
  72. package/reactUtils/index.ts +9 -0
  73. package/testUtils/index.tsx +7 -8
  74. package/typeGuards/index.ts +3 -0
  75. package/utils/index.ts +12 -1
  76. package/zappFrameworkUtils/localStorageHelper.ts +32 -10
  77. package/playerUtils/configurationGenerator.ts +0 -2588
@@ -8,6 +8,7 @@ const {
8
8
 
9
9
  const { tvActionButtonsContainer } = require("./tvAction/container");
10
10
  const { tvActionButton } = require("./tvAction/button");
11
+ const { compact } = require("./_internals");
11
12
 
12
13
  const { spacingKey, absolutePositionElement } = require("./containers");
13
14
 
@@ -46,4 +47,5 @@ module.exports = {
46
47
  tvProgressBar,
47
48
  secondaryImage,
48
49
  getUpdatedSecondaryImageKeys,
50
+ compact,
49
51
  };
@@ -21,7 +21,30 @@ const ZAPPIFEST_FIELDS = {
21
21
  },
22
22
  };
23
23
 
24
- const TV_PLATFORMS = ["tvOS", "android", "LG", "samsung", "roku", "vizio"];
24
+ const TV_PLATFORMS_FOR_FONTS = [
25
+ "tvOS",
26
+ "android",
27
+ "LG",
28
+ "samsung",
29
+ "roku",
30
+ "vizio",
31
+ ];
32
+
33
+ const MOBILE_PLATFORMS = [
34
+ "ios",
35
+ "ios_for_quickbrick",
36
+ "android",
37
+ "android_for_quickbrick",
38
+ ];
39
+
40
+ const TV_PLATFORMS = [
41
+ "android_tv_for_quickbrick",
42
+ "amazon_fire_tv_for_quickbrick",
43
+ "tvos_for_quickbrick",
44
+ "samsung_tv",
45
+ "lg_tv",
46
+ "vizio",
47
+ ];
25
48
 
26
49
  const FontPropsForTVPlatform = (platform) => ({
27
50
  [`${R.toLower(platform)}FontFamily`]: {
@@ -92,7 +115,7 @@ const TV_FONT_KEY_DATA = {
92
115
  name: "focused font color",
93
116
  type: ZAPPIFEST_FIELDS.color_picker,
94
117
  },
95
- ...R.reduce(addTVFontsForPlatform, {}, TV_PLATFORMS),
118
+ ...R.reduce(addTVFontsForPlatform, {}, TV_PLATFORMS_FOR_FONTS),
96
119
  textAlignment: {
97
120
  name: "text alignment",
98
121
  type: ZAPPIFEST_FIELDS.select,
@@ -2083,4 +2106,6 @@ module.exports = {
2083
2106
  TV_CELL_BADGE_FIELDS,
2084
2107
  progressBarFields,
2085
2108
  secondaryImageFields,
2109
+ TV_PLATFORMS,
2110
+ MOBILE_PLATFORMS,
2086
2111
  };
@@ -18,36 +18,6 @@ describe("mobileProgressBar", () => {
18
18
  ]),
19
19
  });
20
20
 
21
- // const timeRemainingLabelConditions = (condition) => ({
22
- // rules: "all_conditions",
23
- // conditional_fields: compact([
24
- // {
25
- // key: "assets/progress_bar_switch",
26
- // condition_value: true,
27
- // },
28
- // {
29
- // key: "assets/progress_bar_time_remaining_label_enable",
30
- // condition_value: true,
31
- // },
32
- // condition,
33
- // ]),
34
- // });
35
-
36
- // const watchedLabelConditions = (condition) => ({
37
- // rules: "all_conditions",
38
- // conditional_fields: compact([
39
- // {
40
- // key: "assets/progress_bar_switch",
41
- // condition_value: true,
42
- // },
43
- // {
44
- // key: "assets/progress_bar_watched_label_enable",
45
- // condition_value: true,
46
- // },
47
- // condition,
48
- // ]),
49
- // });
50
-
51
21
  it("generate progress-bar configuration - enabled and with bottom_of_cell", () => {
52
22
  const enable = true;
53
23
  const hideUnwatched = true;
@@ -8,7 +8,6 @@ const {
8
8
  conditional_horizontal_type,
9
9
  conditional_vertical_type,
10
10
  conditional_horizontal_type_item_fixed,
11
- conditional_horizontal_type_item_dynamic,
12
11
  conditional_horizontal_asset_on,
13
12
  conditional_horizontal_display_type_fixed,
14
13
  } = require("./utils");
@@ -48,7 +47,7 @@ const componentConfigurationFields = [
48
47
  { text: "Right", value: "right" },
49
48
  { text: "Center", value: "center" },
50
49
  ],
51
- ...conditional_horizontal_type_item_dynamic,
50
+ ...conditional_horizontal_type,
52
51
  },
53
52
  {
54
53
  type: "select",
@@ -319,68 +319,3 @@ describe("getRiverFromRoute", () => {
319
319
  expect(getRiverFromRoute({ route, rivers })).toEqual(river);
320
320
  });
321
321
  });
322
-
323
- describe("isPreviousRouteHook", () => {
324
- const { isPreviousRouteHook } = navigationUtils;
325
-
326
- const history = {
327
- entries: [],
328
- };
329
-
330
- it("returns false if it's a root route", () => {
331
- history.entries.push({ pathname: "/river/root" });
332
- const currentResult = isPreviousRouteHook(history.entries);
333
- expect(currentResult).toBe(false);
334
- });
335
-
336
- it("returns false if previous root is not a hook", () => {
337
- history.entries.push({ pathname: "/almostHooks/secondLevel" });
338
- const currentResult = isPreviousRouteHook(history.entries);
339
- expect(currentResult).toBe(false);
340
- });
341
-
342
- it("returns true if previous root is a hook", () => {
343
- history.entries.push({ pathname: "/hooks/ThirdLevel" });
344
- history.entries.push({ pathname: "/almostHooks/forthLevel" });
345
- const currentResult = isPreviousRouteHook(history.entries);
346
- expect(currentResult).toBe(true);
347
- });
348
- });
349
-
350
- describe("getPreviousHooksCount", () => {
351
- const { getPreviousHooksCount } = navigationUtils;
352
-
353
- const history = {
354
- entries: [],
355
- };
356
-
357
- it("returns 0 if it's a root route", () => {
358
- history.entries.push({ pathname: "/river/root" });
359
- const currentResult = getPreviousHooksCount(history);
360
- expect(currentResult).toBe(0);
361
- });
362
-
363
- it("returns 0 if previous root is not a hook", () => {
364
- history.entries.push({ pathname: "/almostHooks/secondLevel" });
365
- const currentResult = getPreviousHooksCount(history);
366
- expect(currentResult).toBe(0);
367
- });
368
-
369
- it("returns 1 if previous root is a hook", () => {
370
- history.entries = [];
371
- history.entries.push({ pathname: "/hooks/ThirdLevel" });
372
- history.entries.push({ pathname: "/almostHooks/forthLevel" });
373
- const currentResult = getPreviousHooksCount(history);
374
- expect(currentResult).toBe(1);
375
- });
376
-
377
- it("returns 2 if 2 previous routes are a hooks", () => {
378
- history.entries = [];
379
- history.entries.push({ pathname: "/almostHooks/forthLevel" });
380
- history.entries.push({ pathname: "/hooks/myHook" });
381
- history.entries.push({ pathname: "/hooks/myHook" });
382
- history.entries.push({ pathname: "/almostHooks/forthLevel" });
383
- const currentResult = getPreviousHooksCount(history);
384
- expect(currentResult).toBe(2);
385
- });
386
- });
@@ -363,37 +363,6 @@ export function getRiverFromRoute({
363
363
  return screenType && screenId ? { screenType, screenId } : null;
364
364
  }
365
365
 
366
- /**
367
- * Function returns true if the previous route (in the react-router history) is a hook plugin
368
- * @param {*} entries - React-Router History Object
369
- * @return boolean
370
- */
371
- export function isPreviousRouteHook(entries: [{ pathname: string }]): boolean {
372
- const previousRoute = entries[entries.length - 2];
373
- if (!previousRoute) return false;
374
-
375
- return R.test(/\/hooks\/.*/g, previousRoute.pathname);
376
- }
377
-
378
- /**
379
- * Function returns number of consecutive hooks that are behind the current route
380
- * @param {*} history - React-Router History Object
381
- * @return true
382
- */
383
- export function getPreviousHooksCount(history: {
384
- entries: [{ pathname: string }];
385
- }): number {
386
- let hooksCount = 0;
387
- let entries = R.clone(history.entries);
388
-
389
- while (isPreviousRouteHook(entries)) {
390
- hooksCount++;
391
- entries = R.init(entries);
392
- }
393
-
394
- return hooksCount;
395
- }
396
-
397
366
  export const usesVideoModal = (
398
367
  item: ZappEntry,
399
368
  rivers: Record<string, ZappRiver>,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "13.0.0-rc.99",
3
+ "version": "14.0.0-alpha.1235043154",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "homepage": "https://github.com/applicaster/quickbrick#readme",
29
29
  "dependencies": {
30
- "@applicaster/applicaster-types": "13.0.0-rc.99",
30
+ "@applicaster/applicaster-types": "14.0.0-alpha.1235043154",
31
31
  "buffer": "^5.2.1",
32
32
  "camelize": "^1.0.0",
33
33
  "dayjs": "^1.11.10",
@@ -1,72 +1,8 @@
1
1
  import * as utils from "../configurationUtils";
2
2
 
3
- const { modifyDefaultConfigValues, parseLanguageTracks } = utils;
4
-
5
- const configuration = {
6
- general: { fields: [{ key: "general_1", initial_value: true }] },
7
- styles: { fields: [{ key: "styles_1", initial_value: true }] },
8
- localizations: {
9
- fields: [{ key: "localizations_1", initial_value: true, label: "label" }],
10
- },
11
- custom_configuration_fields: [
12
- { key: "custom_configuration_fields_1", initial_value: true },
13
- { key: "custom_configuration_fields_2", initial_value: "black" },
14
- {
15
- group: true,
16
- fields: [{ key: "custom_configuration_fields_3", initial_value: "red" }],
17
- },
18
- ],
19
- };
3
+ const { parseLanguageTracks } = utils;
20
4
 
21
5
  describe("utilities", () => {
22
- describe("modifyDefaultConfigValues", () => {
23
- it("should not modify the configuration if a map key doesn't exist in configuration ", function () {
24
- const res = modifyDefaultConfigValues(configuration, {
25
- custom_configuration_fields: {
26
- non_existing_key: { initial_value: "true" },
27
- },
28
- });
29
-
30
- expect(res).toEqual(configuration);
31
- });
32
-
33
- it("should modify the key from mapping", function () {
34
- const currentResult = modifyDefaultConfigValues(configuration, {
35
- styles: { styles_1: { initial_value: false } },
36
- });
37
-
38
- expect(currentResult.styles.fields[0].initial_value).toBe(false);
39
- });
40
-
41
- it("should add extra keys the key from mapping", function () {
42
- const currentResult = modifyDefaultConfigValues(configuration, {
43
- styles: { styles_1: { extra_key: false } },
44
- });
45
-
46
- expect(currentResult.styles.fields[0].extra_key).toBeDefined();
47
- });
48
-
49
- it("should not remove existing keys that aren't being overwritten", function () {
50
- const currentResult = modifyDefaultConfigValues(configuration, {
51
- localizations: { localizations_1: { initial_value: false } },
52
- });
53
-
54
- expect(currentResult.localizations.fields[0].label).toBeDefined();
55
- });
56
-
57
- it("should modify values in groups as well", function () {
58
- const currentResult = modifyDefaultConfigValues(configuration, {
59
- custom_configuration_fields: {
60
- custom_configuration_fields_3: { initial_value: "blue" },
61
- },
62
- });
63
-
64
- expect(
65
- currentResult.custom_configuration_fields[2].fields[0].initial_value
66
- ).toBe("blue");
67
- });
68
- });
69
-
70
6
  describe("parseLanguageTracks", () => {
71
7
  const textTrack = { index: 0, id: "text-0" };
72
8
  const audioTrack = { index: 0, id: "audio-0" };
@@ -0,0 +1,54 @@
1
+ import { getPlayerActionButtons } from "../getPlayerActionButtons";
2
+ import { selectActionButtons } from "../../conf/player/selectors";
3
+
4
+ jest.mock("../../conf/player/selectors", () => ({
5
+ selectActionButtons: jest.fn(),
6
+ }));
7
+
8
+ describe("getPlayerActionButtons", () => {
9
+ afterEach(() => {
10
+ jest.clearAllMocks();
11
+ });
12
+
13
+ it("returns an empty array if selectActionButtons returns undefined", () => {
14
+ (selectActionButtons as jest.Mock).mockReturnValue(undefined);
15
+ const result = getPlayerActionButtons({});
16
+ expect(result).toEqual([]);
17
+ });
18
+
19
+ it("returns an empty array if selectActionButtons returns null", () => {
20
+ (selectActionButtons as jest.Mock).mockReturnValue(null);
21
+ const result = getPlayerActionButtons({});
22
+ expect(result).toEqual([]);
23
+ });
24
+
25
+ it("returns an empty array if selectActionButtons returns empty string", () => {
26
+ (selectActionButtons as jest.Mock).mockReturnValue("");
27
+ const result = getPlayerActionButtons({});
28
+ expect(result).toEqual([]);
29
+ });
30
+
31
+ it("returns the first two trimmed action buttons", () => {
32
+ (selectActionButtons as jest.Mock).mockReturnValue(" play , pause , stop ");
33
+ const result = getPlayerActionButtons({});
34
+ expect(result).toEqual(["play", "pause"]);
35
+ });
36
+
37
+ it("returns only one button if only one is present", () => {
38
+ (selectActionButtons as jest.Mock).mockReturnValue(" play ");
39
+ const result = getPlayerActionButtons({});
40
+ expect(result).toEqual(["play"]);
41
+ });
42
+
43
+ it("trims whitespace from button names", () => {
44
+ (selectActionButtons as jest.Mock).mockReturnValue(" play , pause ");
45
+ const result = getPlayerActionButtons({});
46
+ expect(result).toEqual(["play", "pause"]);
47
+ });
48
+
49
+ it("returns an empty array if selectActionButtons returns only commas", () => {
50
+ (selectActionButtons as jest.Mock).mockReturnValue(" , , ");
51
+ const result = getPlayerActionButtons({});
52
+ expect(result).toEqual(["", ""]);
53
+ });
54
+ });
@@ -0,0 +1,71 @@
1
+ import { getAllFields, getConfigurationDiff } from "../utils";
2
+
3
+ describe("getAllFields", () => {
4
+ it("should return all field keys from flat configs", () => {
5
+ const config1 = {
6
+ fields: [{ key: "foo" }, { key: "bar" }],
7
+ };
8
+
9
+ const config2 = {
10
+ fields: [{ key: "baz" }],
11
+ };
12
+
13
+ expect(getAllFields(config1, config2)).toEqual(["foo", "bar", "baz"]);
14
+ });
15
+
16
+ it("should handle grouped fields", () => {
17
+ const config = {
18
+ fields: [
19
+ {
20
+ group: true,
21
+ fields: [{ key: "grouped1" }, { key: "grouped2" }],
22
+ },
23
+ { key: "single" },
24
+ ],
25
+ };
26
+
27
+ expect(getAllFields(config)).toEqual(["grouped1", "grouped2", "single"]);
28
+ });
29
+
30
+ it("should filter out fields without a key", () => {
31
+ const config = {
32
+ fields: [{ key: "foo" }, { notAKey: "bar" }],
33
+ };
34
+
35
+ expect(getAllFields(config)).toEqual(["foo"]);
36
+ });
37
+
38
+ it("should return an empty array if no fields are present", () => {
39
+ expect(getAllFields({})).toEqual([]);
40
+ });
41
+ });
42
+
43
+ describe("getConfigurationDiff", () => {
44
+ it("should return keys in defaultConfig not present in config", () => {
45
+ const defaultConfig = ["foo", "bar", "baz"];
46
+ const config = { foo: 1, baz: 2 };
47
+
48
+ expect(getConfigurationDiff(defaultConfig, config)).toEqual(["bar"]);
49
+ });
50
+
51
+ it("should return all keys if config is empty", () => {
52
+ const defaultConfig = ["foo", "bar"];
53
+ const config = {};
54
+
55
+ expect(getConfigurationDiff(defaultConfig, config)).toEqual(["foo", "bar"]);
56
+ });
57
+
58
+ it("should return an empty array if all keys are present", () => {
59
+ const defaultConfig = ["foo"];
60
+ const config = { foo: 1 };
61
+
62
+ expect(getConfigurationDiff(defaultConfig, config)).toEqual([]);
63
+ });
64
+
65
+ it("should return defaultConfig if config has no matching keys", () => {
66
+ const defaultConfig = ["foo", "bar"];
67
+ const config = { baz: 1 };
68
+
69
+ expect(getConfigurationDiff(defaultConfig, config)).toEqual(["foo", "bar"]);
70
+ });
71
+ });
@@ -0,0 +1 @@
1
+ export * from "./utils";
@@ -0,0 +1,31 @@
1
+ import {
2
+ flatMap,
3
+ get,
4
+ flatten,
5
+ difference,
6
+ } from "@applicaster/zapp-react-native-utils/utils";
7
+
8
+ const extractFields = (field: any) => {
9
+ if (field.group === true) {
10
+ return field.fields;
11
+ }
12
+
13
+ return field;
14
+ };
15
+
16
+ export const getAllFields = (...configs: any[]) => {
17
+ const allFields = flatMap(configs, (config) => get(config, "fields", []));
18
+
19
+ const processedFields = flatten(allFields.map(extractFields))
20
+ .map((field) => get(field, "key"))
21
+ .filter(Boolean);
22
+
23
+ return processedFields;
24
+ };
25
+
26
+ export const getConfigurationDiff = (
27
+ defaultConfig,
28
+ config: Record<string, any>
29
+ ) => {
30
+ return difference(defaultConfig, Object.keys(config));
31
+ };
@@ -1,50 +1,6 @@
1
1
  import { parseJsonIfNeeded } from "../functionUtils";
2
2
  import * as R from "ramda";
3
3
 
4
- import { getNativeName as nativeNameUtil } from "../localizationUtils/localeLanguage";
5
-
6
- export const modifyDefaultConfigValues = (
7
- configuration: ConfigurationKeys,
8
- mapping: ConfigValuesMapping
9
- ): DefaultConfiguration => {
10
- return R.mapObjIndexed((value, key) => {
11
- const isFieldlessKey = key === "custom_configuration_fields";
12
- const keyMapping = mapping[key];
13
- const fields = value?.fields || value;
14
-
15
- if (!keyMapping) {
16
- return value;
17
- }
18
-
19
- const mapper = (obj) => {
20
- if (obj.fields) {
21
- return R.mergeLeft({ fields: R.map(mapper)(obj.fields) })(obj);
22
- }
23
-
24
- return R.mergeLeft(keyMapping?.[obj.key])(obj);
25
- };
26
-
27
- const mappedFields = R.map(mapper)(fields);
28
-
29
- return R.unless(() => isFieldlessKey, R.objOf("fields"))(mappedFields);
30
- })(configuration);
31
- };
32
-
33
- export function nativeName(localeCode) {
34
- try {
35
- const {
36
- getNativeName,
37
- } = require("@applicaster/zapp-react-native-utils/localizationUtils/localeLanguage");
38
-
39
- return getNativeName(localeCode);
40
- } catch (error) {
41
- // eslint-disable-next-line no-console
42
- console.warn("Could not load localeLanguage utils from QB", error);
43
-
44
- return nativeNameUtil(localeCode);
45
- }
46
- }
47
-
48
4
  const setTrackType = R.curry(
49
5
  (
50
6
  type: QuickBrickPlayer.TrackType,
@@ -0,0 +1,17 @@
1
+ import { take, map, trim } from "lodash";
2
+ import { selectActionButtons } from "../conf/player/selectors";
3
+
4
+ /**
5
+ * Returns the first two action buttons from the configuration.
6
+ * @param {Object} configuration - The player configuration object.
7
+ * @returns {Array} An array containing the first two action buttons.
8
+ */
9
+ export const getPlayerActionButtons = (configuration: any) => {
10
+ const buttonsString = selectActionButtons(configuration);
11
+
12
+ if (!buttonsString) {
13
+ return [];
14
+ }
15
+
16
+ return take(map(buttonsString.split(","), trim), 2);
17
+ };
@@ -1,7 +1,13 @@
1
1
  import * as R from "ramda";
2
2
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
3
+ import { isString } from "@applicaster/zapp-react-native-utils/typeGuards";
4
+ import { isFilledArray } from "@applicaster/zapp-react-native-utils/arrayUtils";
5
+ import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
6
+
3
7
  import { getBoolFromConfigValue } from "../configurationUtils";
4
8
 
9
+ export { getPlayerActionButtons } from "./getPlayerActionButtons";
10
+
5
11
  /**
6
12
  * Gets duration value from player manager, and from extensions
7
13
  * then checks whether the value from either is a not a valid number
@@ -72,3 +78,22 @@ function isLiveByManager(): boolean {
72
78
  export function isLive(entry: ZappEntry): boolean {
73
79
  return isEntryLive(entry) || isLiveByManager();
74
80
  }
81
+
82
+ export const isAudioItem = (item: Option<ZappEntry>) => {
83
+ if (
84
+ isString(item?.content?.type) &&
85
+ item?.content?.type?.includes?.("audio")
86
+ ) {
87
+ return true;
88
+ }
89
+
90
+ if (isString(item?.type?.value) && item?.type?.value?.includes?.("audio")) {
91
+ return true;
92
+ }
93
+
94
+ return false;
95
+ };
96
+
97
+ export const isInlineTV = (screenData) => {
98
+ return isTV() && isFilledArray(screenData?.ui_components);
99
+ };
@@ -1,34 +1,37 @@
1
1
  import * as React from "react";
2
- import * as R from "ramda";
3
- import generateConfiguration from "./configurationGenerator";
4
2
  import { createLogger } from "../logger";
3
+ import { createConfig } from "../manifestUtils/createConfig";
4
+ import { getAllFields, getConfigurationDiff } from "./_internals";
5
5
 
6
6
  export const logger = createLogger({
7
7
  category: "useValidatePlayerConfig",
8
8
  subsystem: "useValidatePlayerConfig",
9
9
  });
10
10
 
11
- const configuration = generateConfiguration();
11
+ /** Default Player Configuration */
12
+ const {
13
+ styles,
14
+ general,
15
+ localizations,
16
+ custom_configuration_fields,
17
+ }: DefaultConfiguration = createConfig(
18
+ () => {
19
+ return {};
20
+ },
21
+ { extend: "player" }
22
+ ) as any;
23
+
24
+ const QBPlayerConfigFields = getAllFields(
25
+ styles,
26
+ general,
27
+ localizations,
28
+ custom_configuration_fields
29
+ );
12
30
 
13
31
  export const useValidatePlayerConfig = (config) => {
14
32
  React.useEffect(() => {
15
33
  try {
16
- const QBPlayerConfigFields = R.compose(
17
- R.map(R.prop("key")),
18
- R.flatten,
19
- R.map(R.compose(R.when(R.propEq("group", true), R.prop("fields")))),
20
- R.concat
21
- )(
22
- configuration.styles.fields,
23
- configuration.general.fields,
24
- configuration.localizations.fields,
25
- configuration.custom_configuration_fields
26
- );
27
-
28
- const diff = R.compose(
29
- R.difference(QBPlayerConfigFields),
30
- R.keys
31
- )(config);
34
+ const diff = getConfigurationDiff(QBPlayerConfigFields, config);
32
35
 
33
36
  logger.log_info(
34
37
  "Missing following configuration properties. Some elements of the player may not work correctly. Check QuickBrickPlayerPlugin for the configuration reference https://github.com/applicaster/QuickBrick/tree/main/plugins/zapp-react-native-default-player/manifests",
@@ -14,10 +14,10 @@ export function useAppState(returnIsActive) {
14
14
  };
15
15
 
16
16
  React.useEffect(() => {
17
- AppState.addEventListener("change", setAppState);
17
+ const subscription = AppState.addEventListener("change", setAppState);
18
18
 
19
19
  return () => {
20
- AppState.removeEventListener("change", setAppState);
20
+ subscription.remove();
21
21
  };
22
22
  }, []);
23
23