@applicaster/zapp-react-native-utils 14.0.0-alpha.8387612031 → 14.0.0-alpha.8419134002

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 (31) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +1 -1
  2. package/analyticsUtils/AnalyticsEvents/helper.ts +81 -0
  3. package/analyticsUtils/AnalyticsEvents/sendOnClickEvent.ts +14 -4
  4. package/analyticsUtils/__tests__/analyticsUtils.test.js +14 -0
  5. package/analyticsUtils/events.ts +8 -0
  6. package/appUtils/accessibilityManager/index.ts +3 -3
  7. package/audioPlayerUtils/index.ts +104 -0
  8. package/focusManager/FocusManager.ts +4 -6
  9. package/manifestUtils/_internals/getDefaultConfiguration.js +28 -0
  10. package/manifestUtils/{_internals.js → _internals/index.js} +2 -25
  11. package/manifestUtils/createConfig.js +4 -1
  12. package/manifestUtils/defaultManifestConfigurations/player.js +1239 -200
  13. package/manifestUtils/progressBar/__tests__/mobileProgressBar.test.js +0 -30
  14. package/package.json +2 -2
  15. package/playerUtils/__tests__/configurationUtils.test.ts +1 -65
  16. package/playerUtils/_internals/__tests__/utils.test.ts +71 -0
  17. package/playerUtils/_internals/index.ts +1 -0
  18. package/playerUtils/_internals/utils.ts +31 -0
  19. package/playerUtils/configurationUtils.ts +0 -44
  20. package/playerUtils/getPlayerActionButtons.ts +1 -1
  21. package/playerUtils/useValidatePlayerConfig.tsx +22 -19
  22. package/reactHooks/feed/useBatchLoading.ts +1 -1
  23. package/reactHooks/feed/usePipesCacheReset.ts +1 -1
  24. package/reactHooks/navigation/useIsScreenActive.ts +9 -5
  25. package/reactHooks/screen/useScreenContext.ts +1 -1
  26. package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +2 -1
  27. package/riverComponetsMeasurementProvider/index.tsx +1 -1
  28. package/services/js2native.ts +1 -0
  29. package/time/BackgroundTimer.ts +5 -3
  30. package/utils/index.ts +7 -0
  31. package/playerUtils/configurationGenerator.ts +0 -2572
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "14.0.0-alpha.8387612031",
3
+ "version": "14.0.0-alpha.8419134002",
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": "14.0.0-alpha.8387612031",
30
+ "@applicaster/applicaster-types": "14.0.0-alpha.8419134002",
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,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,
@@ -1,4 +1,4 @@
1
- import { take, map, trim } from "lodash";
1
+ import { map, take, trim } from "../utils";
2
2
  import { selectActionButtons } from "../conf/player/selectors";
3
3
 
4
4
  /**
@@ -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",
@@ -10,7 +10,7 @@ import {
10
10
  getSearchContext,
11
11
  } from "@applicaster/zapp-react-native-utils/reactHooks";
12
12
  import { isGallery } from "@applicaster/zapp-react-native-utils/componentsUtils";
13
- import { useScreenContext } from "../screen/useScreenContext";
13
+ import { useScreenContext } from "../screen";
14
14
 
15
15
  type Options = {
16
16
  initialBatchSize?: number;
@@ -5,7 +5,7 @@ import { getDatasourceUrl } from "@applicaster/zapp-react-native-ui-components/D
5
5
  import { usePipesContexts } from "@applicaster/zapp-react-native-ui-components/Decorators/RiverFeedLoader/utils/usePipesContexts";
6
6
  import { clearPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
7
7
 
8
- import { useRoute } from "../navigation/useRoute";
8
+ import { useRoute } from "../navigation";
9
9
 
10
10
  /**
11
11
  * reset river components cache when screen is unmounted
@@ -1,3 +1,4 @@
1
+ import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
1
2
  import { useNavigation } from "./useNavigation";
2
3
  import { usePathname } from "./usePathname";
3
4
 
@@ -6,11 +7,14 @@ export const useIsScreenActive = () => {
6
7
  const pathname = usePathname();
7
8
  const { currentRoute, videoModalState } = useNavigation();
8
9
 
9
- if (
10
- videoModalState.visible &&
11
- ["FULLSCREEN", "MAXIMIZED", "PIP"].includes(videoModalState.mode)
12
- ) {
13
- return false;
10
+ if (videoModalState.visible) {
11
+ if (pathname.includes(ROUTE_TYPES.VIDEO_MODAL)) {
12
+ return true;
13
+ }
14
+
15
+ if (["FULLSCREEN", "MAXIMIZED", "PIP"].includes(videoModalState.mode)) {
16
+ return false;
17
+ }
14
18
  }
15
19
 
16
20
  return pathname === currentRoute;
@@ -2,7 +2,7 @@ import { useContext, useMemo } from "react";
2
2
 
3
3
  import { useModalNavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ModalNavigationContext";
4
4
  import { useNestedNavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NestedNavigationContext";
5
- import { useNavigation } from "../navigation/useNavigation";
5
+ import { useNavigation } from "../navigation";
6
6
 
7
7
  import { ScreenContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenContext";
8
8
  import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
@@ -1,7 +1,8 @@
1
+ /* eslint-disable no-console */
1
2
  import React from "react";
2
3
  import { render, screen } from "@testing-library/react-native";
3
4
  import { Text } from "react-native";
4
- import { ZStoreProvider, useZStore } from "../ZStoreProvider";
5
+ import { useZStore, ZStoreProvider } from "../ZStoreProvider";
5
6
  import { useStore } from "zustand";
6
7
 
7
8
  interface TestState {
@@ -3,7 +3,7 @@ import { NativeModules, StyleSheet, View } from "react-native";
3
3
  import { getXray } from "@applicaster/zapp-react-native-utils/logger";
4
4
 
5
5
  import { isApplePlatform, isWeb } from "../reactUtils";
6
- import { useRivers } from "../reactHooks/state";
6
+ import { useRivers } from "../reactHooks";
7
7
 
8
8
  const layoutReducer = (state, { payload }) => {
9
9
  return state.map((item, index, _state) => ({
@@ -496,6 +496,7 @@ async function removeStorageListenerHandler(payload: { listenerId?: string }) {
496
496
  function log({ level, messages }) {
497
497
  try {
498
498
  const parsedMessages = parseJsonIfNeeded(messages);
499
+ // eslint-disable-next-line no-console
499
500
  const logFn = console[level] || console.log;
500
501
 
501
502
  if (Array.isArray(parsedMessages)) {
@@ -13,13 +13,15 @@ class BackgroundTimer {
13
13
 
14
14
  const EventEmitter = platformSelect({
15
15
  android: DeviceEventEmitter,
16
- ios: undefined,
16
+ android_tv: DeviceEventEmitter,
17
+ amazon: DeviceEventEmitter, // probably does not exist and uses android_tv
17
18
  default: undefined,
18
19
  });
19
20
 
20
21
  EventEmitter?.addListener("BackgroundTimer.timer.fired", (id: number) => {
21
- if (this.callbacks[id]) {
22
- const callback = this.callbacks[id];
22
+ const callback = this.callbacks[id];
23
+
24
+ if (callback) {
23
25
  delete this.callbacks[id];
24
26
  callback();
25
27
  }
package/utils/index.ts CHANGED
@@ -10,4 +10,11 @@ export {
10
10
  isNil,
11
11
  isEmpty,
12
12
  get,
13
+ has,
14
+ flatMap,
15
+ difference,
16
+ take,
17
+ map,
18
+ trim,
19
+ toString,
13
20
  } from "lodash";