@applicaster/zapp-react-native-utils 13.0.0-alpha.5771418585 → 13.0.0-alpha.5953040243

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.
@@ -0,0 +1,130 @@
1
+ const defaultPlatforms = {
2
+ tvos: "tvOS",
3
+ android_tv: "Android TV",
4
+ lg_tv: "LG TV",
5
+ samsung_tv: "Samsung TV",
6
+ };
7
+
8
+ const global_defaults = {
9
+ fontSize: 20,
10
+ lineHeight: 40,
11
+ letterSpacing: 0.4,
12
+ };
13
+
14
+ const generateFontConfiguration = (platforms = defaultPlatforms) => {
15
+ const platformEntries = Object.entries(platforms);
16
+ const defaultsEntries = Object.entries(global_defaults);
17
+ const splitCamelCase = (str) => str.replace(/([a-z](?=[A-Z]))/g, "$1_");
18
+
19
+ return platformEntries.reduce((acc, [platformKey, platformValue]) => {
20
+ acc.push(
21
+ ...defaultsEntries.reduce((acc2, [valueKey, defaultValue]) => {
22
+ acc2.push({
23
+ type: "number_input",
24
+ label: `${platformValue} ${splitCamelCase(valueKey).replace(
25
+ "_",
26
+ " "
27
+ )}`,
28
+ key: `${platformKey}_${splitCamelCase(valueKey)}`.toLowerCase(),
29
+ initial_value: defaultValue,
30
+ });
31
+
32
+ return acc2;
33
+ }, [])
34
+ );
35
+
36
+ return acc;
37
+ }, []);
38
+ };
39
+
40
+ const conditional_rule = (key, condition_value) => ({
41
+ key,
42
+ condition_value,
43
+ });
44
+
45
+ const createConditionalConfig = (rules, matchAll = false) => ({
46
+ rules: matchAll ? "all_conditions" : "conditional",
47
+ conditional_fields: rules.map((field) => conditional_rule(...field)),
48
+ });
49
+
50
+ const conditional_horizontal_type = createConditionalConfig([
51
+ ["styles/screen_picker_type", "horizontal"],
52
+ ]);
53
+
54
+ const conditional_vertical_type = createConditionalConfig([
55
+ ["styles/screen_picker_type", "vertical"],
56
+ ]);
57
+
58
+ const conditional_horizontal_type_item_fixed = createConditionalConfig(
59
+ [
60
+ ["styles/screen_picker_type", "horizontal"],
61
+ ["styles/screen_picker_item_size", "fixed"],
62
+ ],
63
+ true
64
+ );
65
+
66
+ const conditional_horizontal_type_item_dynamic = createConditionalConfig(
67
+ [
68
+ ["styles/screen_picker_type", "horizontal"],
69
+ ["screen_picker_horizontal_display_type", "dynamic"],
70
+ ],
71
+ true
72
+ );
73
+
74
+ const conditional_horizontal_display_type_fixed = createConditionalConfig(
75
+ [
76
+ ["styles/screen_picker_type", "horizontal"],
77
+ ["styles/screen_picker_horizontal_display_type", "fixed"],
78
+ ],
79
+ true
80
+ );
81
+
82
+ const conditional_horizontal_asset_on = createConditionalConfig(
83
+ [
84
+ ["styles/screen_picker_type", "horizontal"],
85
+ ["styles/screen_picker_asset_switch", true],
86
+ ],
87
+ true
88
+ );
89
+
90
+ const createVariationFields = ({
91
+ prefix = "screen_picker",
92
+ key,
93
+ type = "number_input",
94
+ label = "",
95
+ variants: [a, b],
96
+ }) => {
97
+ return [
98
+ {
99
+ type,
100
+ key: `${prefix}${prefix.length > 0 ? "_" : ""}${
101
+ a?.key ?? "vertical"
102
+ }_${key}`,
103
+ label: a?.label ?? label,
104
+ initial_value: a.initial_value,
105
+ ...conditional_vertical_type,
106
+ },
107
+ {
108
+ type,
109
+ key: `${prefix}${prefix.length > 0 ? "_" : ""}${
110
+ b.key ?? "horizontal"
111
+ }_${key}`,
112
+ label: b?.label ?? label,
113
+ initial_value: b.initial_value,
114
+ ...conditional_horizontal_type,
115
+ },
116
+ ];
117
+ };
118
+
119
+ module.exports = {
120
+ generateFontConfiguration,
121
+ createVariationFields,
122
+ createConditionalConfig,
123
+ conditional_rule,
124
+ conditional_horizontal_type,
125
+ conditional_vertical_type,
126
+ conditional_horizontal_type_item_fixed,
127
+ conditional_horizontal_type_item_dynamic,
128
+ conditional_horizontal_display_type_fixed,
129
+ conditional_horizontal_asset_on,
130
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "13.0.0-alpha.5771418585",
3
+ "version": "13.0.0-alpha.5953040243",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,11 +28,9 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "13.0.0-alpha.5771418585",
31
+ "@applicaster/applicaster-types": "13.0.0-alpha.5953040243",
32
32
  "buffer": "^5.2.1",
33
33
  "camelize": "^1.0.0",
34
- "create-react-context": "^0.2.3",
35
- "create-react-ref": "^0.1.0",
36
34
  "dayjs": "^1.11.10",
37
35
  "memoizee": "0.4.15",
38
36
  "prop-types": "^15.0.0",
@@ -42,8 +40,8 @@
42
40
  "@applicaster/zapp-pipes-v2-client": "*",
43
41
  "@react-native-community/netinfo": "*",
44
42
  "immer": "*",
45
- "react": "17.0.2",
46
- "react-native": "0.68.6",
43
+ "react": "*",
44
+ "react-native": "*",
47
45
  "uglify-js": "*",
48
46
  "validate-color": "*",
49
47
  "zustand": "*"
@@ -3,5 +3,8 @@ export const useNavigation = jest.fn(() => ({
3
3
  screenData: {
4
4
  name: "someName",
5
5
  },
6
+ videoModalState: {
7
+ visible: false,
8
+ },
6
9
  currentRoute: "someRoute",
7
10
  }));
@@ -23,7 +23,7 @@ export enum SEEK_STRATEGY {
23
23
  }
24
24
 
25
25
  const CONFIG_TAP_SEEK = {
26
- CLICKS_BEFORE_PAUSE: 1,
26
+ CLICKS_BEFORE_PAUSE: 0,
27
27
  };
28
28
 
29
29
  const CONFIG_LONG_PRESS = {
@@ -93,8 +93,6 @@ export class TVSeekController
93
93
  this.isPlayerInitiallyPaused = this.playerController.isPaused();
94
94
  }
95
95
 
96
- log_debug(`handleStartSeek: seekType: ${seekType}, initiallyPaused: ${this.isPlayerInitiallyPaused}, isPlayerPaused: ${this.playerController.isPaused()}`);
97
-
98
96
  this.clearLongPressThresholdTimeout();
99
97
  this.clearSeekCompleteTimeout();
100
98
  this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
@@ -107,36 +105,27 @@ export class TVSeekController
107
105
  };
108
106
 
109
107
  onForwardPress = (): boolean => {
110
- log_debug("onForwardPress:");
111
-
112
108
  this.handleStartSeek(SEEK_TYPE.FORWARD);
113
109
 
114
110
  return true;
115
111
  };
116
112
 
117
113
  onRewindPress = (): boolean => {
118
- log_debug("onRewindPress:");
119
-
120
114
  this.handleStartSeek(SEEK_TYPE.REWIND);
121
115
 
122
116
  return true;
123
117
  };
124
118
 
125
119
  onSeekEnd = () => {
126
- log_debug("onSeekEnd: Seek ended");
127
120
  this.clearLongPressThresholdTimeout();
128
121
  this.currentSeekController.onSeekEnd();
129
122
  };
130
123
 
131
124
  onRewindPressOut = () => {
132
- log_debug("onRewindPressOut:");
133
-
134
125
  this.onSeekEnd();
135
126
  };
136
127
 
137
128
  onForwardPressOut = () => {
138
- log_debug("onForwardPressOut:");
139
-
140
129
  this.onSeekEnd();
141
130
  };
142
131
 
@@ -149,9 +138,7 @@ export class TVSeekController
149
138
  };
150
139
 
151
140
  handleDelayedSeek = (offset: number = 0) => {
152
- if (this.delayedSeekPosition === null) {
153
- void this.handlePlayerPause();
154
- }
141
+ this.handlePlayerPause();
155
142
 
156
143
  const currentPos =
157
144
  this.delayedSeekPosition === null
@@ -187,46 +174,36 @@ export class TVSeekController
187
174
  }
188
175
  }
189
176
 
190
- log_debug(`handleDelayedSeek: currentPos: ${currentPos} targetPos:${targetPos}, initiallyPaused: ${this.isPlayerInitiallyPaused}`);
191
-
192
177
  this.delayedSeekPosition = targetPos;
193
178
  this.delayedSeekProgressSubject.next(targetPos);
194
179
  };
195
180
 
196
- handleSeekTo = async (newPosition: number) => {
197
- await this.playerController.seekTo(newPosition);
198
-
199
- log_debug(
200
- `handleSeekTo: isPlayerInitiallyPaused: ${this.isPlayerInitiallyPaused} CallPlayerPlay: ${this.isPlayerInitiallyPaused ? "NO" : "YES"}`
201
- );
181
+ handleSeekTo = (newPosition: number) => {
182
+ this.playerController.seekTo(newPosition);
202
183
 
203
184
  if (!this.isPlayerInitiallyPaused) {
204
- await this.playerController.play();
185
+ this.playerController.play();
205
186
  }
206
187
  };
207
188
 
208
- handleSeek = async (offset: number) => {
209
- await this.playerController[this.currentSeekType](offset);
210
-
211
- log_debug(
212
- `handleSeek: isPlayerInitiallyPaused: ${this.isPlayerInitiallyPaused} CallPlayerPlay: ${this.isPlayerInitiallyPaused ? "NO" : "YES"}`
213
- );
189
+ handleSeek = (offset: number) => {
190
+ this.playerController[this.currentSeekType](offset);
214
191
 
215
192
  if (!this.isPlayerInitiallyPaused) {
216
- await this.playerController.play();
193
+ this.playerController.play();
217
194
  }
218
195
  };
219
196
 
220
197
  handleSeekComplete = () => {
221
198
  this.clearSeekCompleteTimeout();
222
199
 
223
- this.seekEndTimeout = setTimeout(async () => {
200
+ this.seekEndTimeout = setTimeout(() => {
224
201
  if (this.delayedSeekPosition !== null) {
225
- await this.handleSeekTo(this.delayedSeekPosition);
202
+ this.handleSeekTo(this.delayedSeekPosition);
226
203
  }
227
204
 
228
205
  log_debug(
229
- `handleSeekComplete: Seek finished, type: ${this.currentSeekController.title}, seekPosition: ${this.delayedSeekPosition}, playerPaused: ${this.playerController.isPaused()}. Reset all states and seek position.`
206
+ `handleSeekComplete: Seek finished, type: ${this.currentSeekController.title}, seekPosition: ${this.delayedSeekPosition}. Reset all states and seek position.`
230
207
  );
231
208
 
232
209
  this.resetAll();
@@ -237,16 +214,12 @@ export class TVSeekController
237
214
  return this.delayedSeekPosition !== null;
238
215
  };
239
216
 
240
- handlePlayerPause = async () => {
241
- log_debug(
242
- `handleSeek: handlePlayerPause isPlayerPaused: ${this.playerController.isPaused()}`
243
- );
244
-
217
+ handlePlayerPause = () => {
245
218
  if (this.playerController.isPaused()) {
246
219
  return;
247
220
  }
248
221
 
249
- await this.playerController.pause();
222
+ this.playerController.pause();
250
223
  };
251
224
 
252
225
  clearSeekCompleteTimeout = () => {
@@ -12,8 +12,6 @@ interface TapPressConfig {
12
12
 
13
13
  export class TapSeekController implements ISeekController {
14
14
  readonly title = "TapSeek";
15
- private lastFastSeekExit = 0;
16
-
17
15
  constructor(
18
16
  private seekControllerDelegate: ISeekControllerDelegate,
19
17
  private seekIncrementalStrategy: SeekIncrementalBaseStrategy,
@@ -25,18 +23,13 @@ export class TapSeekController implements ISeekController {
25
23
 
26
24
  const skipTime = this.seekIncrementalStrategy.getSkipTime();
27
25
  const seekMultiplier = this.seekIncrementalStrategy.getSkipMultiplier();
28
- const cooldown = Date.now() - this.lastFastSeekExit > 1000;
29
26
 
30
27
  if (seekMultiplier > this.config.CLICKS_BEFORE_PAUSE) {
31
28
  log_debug(
32
29
  `${this.title}: handle delayed seek type:${seekType} - skipTime: ${skipTime}, seekMultiplier: ${seekMultiplier}.`
33
30
  );
34
31
 
35
- if (cooldown) {
36
- this.seekControllerDelegate.handleDelayedSeek(skipTime);
37
- } else {
38
- this.seekControllerDelegate.handleSeek(skipTime);
39
- }
32
+ this.seekControllerDelegate.handleDelayedSeek(skipTime);
40
33
  } else {
41
34
  log_debug(
42
35
  `${this.title}: handle seek type:${seekType} - skipTime: ${skipTime}.`
@@ -53,8 +46,8 @@ export class TapSeekController implements ISeekController {
53
46
  };
54
47
 
55
48
  reset = () => {
56
- log_debug(`${this.title}: Reset states`);
57
- this.lastFastSeekExit = Date.now();
49
+ log_debug("{this.title}: Reset states");
50
+
58
51
  this.seekIncrementalStrategy.reset();
59
52
  };
60
53
  }
@@ -7,7 +7,7 @@ import {
7
7
  componentDidMount,
8
8
  } from "./fixtures";
9
9
 
10
- import { attachLifeCycleMethods, createReactRef, mergeChildrenProps } from "..";
10
+ import { attachLifeCycleMethods, mergeChildrenProps } from "..";
11
11
 
12
12
  describe("attachLifeCycleMethods", () => {
13
13
  let addLifeCycleMethodsSpy;
@@ -41,24 +41,6 @@ describe("attachLifeCycleMethods", () => {
41
41
  });
42
42
  });
43
43
 
44
- describe("createReactRef", () => {
45
- it("calls the React.createRef function if it exists", () => {
46
- jest.clearAllMocks();
47
-
48
- const ref = createReactRef();
49
- expect(ref).toHaveProperty("current");
50
- });
51
-
52
- it("calls the polyfill if React.createRef doesn't exist", () => {
53
- jest.clearAllMocks();
54
- const originalCreateRef = React.createRef;
55
- React.createRef = undefined;
56
- const ref = createReactRef();
57
- expect(ref).toHaveProperty("current");
58
- React.createRef = originalCreateRef;
59
- });
60
- });
61
-
62
44
  describe("mergeChildrenProps", () => {
63
45
  it("returns the cloned children with the merged props", () => {
64
46
  const Egg = () => React.createElement("Egg");
@@ -1,3 +1,5 @@
1
+ import { createContext } from "../";
2
+
1
3
  jest.mock("react", () => ({
2
4
  ...jest.requireActual("react"),
3
5
  createContext: jest.fn(() => ({
@@ -6,8 +8,6 @@ jest.mock("react", () => ({
6
8
  })),
7
9
  }));
8
10
 
9
- const { createContext } = require("../index");
10
-
11
11
  const mockedProvider = jest.fn();
12
12
  const mockedWithConsumer = jest.fn();
13
13
  const mockedWithProvider = jest.fn();
@@ -33,7 +33,12 @@ export const getSetterName: (property: string) => string = R.compose(
33
33
  export function createContextSetters(
34
34
  properties: string[],
35
35
  component: any,
36
- options: any = {}
36
+ options: {
37
+ stateValidator?: (
38
+ obj: { property: string; value: unknown },
39
+ oldValue: unknown
40
+ ) => boolean;
41
+ } = {}
37
42
  ) {
38
43
  const { stateValidator = R.T } = options;
39
44
 
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import createReactContext from "create-react-context";
3
2
  import * as R from "ramda";
4
3
 
5
4
  import { getSetterName, NOOP } from "./helpers";
@@ -7,33 +6,20 @@ import { createProvider } from "./provider";
7
6
  import { createWithConsumerDecorator } from "./withConsumer";
8
7
  import { createWithProviderDecorator } from "./withProvider";
9
8
 
10
- const reactContextCreator = React.createContext;
11
-
12
- // Depending on the version of React used, the `createContext` function may not be available
13
- // if this is the case, we fall back to a polyfill library
14
- const contextCreatorFn =
15
- reactContextCreator && typeof reactContextCreator === "function"
16
- ? reactContextCreator
17
- : createReactContext;
18
-
19
- /**
20
- * @typedef Context
21
- * @property {Object} Context.Provider react class component to use as context provider
22
- * @property {Function} Context.Consumer react functional component to use as context consumer
23
- * @property {Function} Context.withProvider HOC to apply the context provider
24
- * @property {function} Context.withConsumer HOC to apply the context consumer. passes the context as props
25
- * @property {React.Context} Context.ReactContext React context object
26
- * to the wrapped component
27
- */
28
-
29
9
  /**
30
10
  * Creates a React Context and returns consumer & providers components & decorators to interact
31
11
  * with this context.
32
- * @param {Object} initialContext map of context properties and their initial values
33
- * @param {Function} stateValidator optional predicate to tell whether the state update is valid or not
34
- * @returns {Context} Object containing the context components & decorators {@link Context}
12
+ * @param initialContext map of context properties and their initial values
13
+ * @param stateValidator optional predicate to tell whether the state update is valid or not
14
+ * @returns Object containing the context components & decorators
35
15
  */
36
- export function createContext(initialContext, stateValidator = R.T) {
16
+ export function createContext(
17
+ initialContext: Record<string, any>,
18
+ stateValidator: (
19
+ obj: { property: string; value: unknown },
20
+ oldValue: unknown
21
+ ) => boolean = R.T
22
+ ) {
37
23
  // first we extract the properties name, and create setters name for those
38
24
  const contextPropertiesNames = R.keys(initialContext);
39
25
  const contextSettersNames = R.map(getSetterName, contextPropertiesNames);
@@ -41,7 +27,7 @@ export function createContext(initialContext, stateValidator = R.T) {
41
27
  // we create a React Context with the properties & their setters, assigning a noop function
42
28
  // temporarily (will be overriden by proper setters in the provider component)
43
29
  const ReactContext = R.compose(
44
- contextCreatorFn,
30
+ React.createContext,
45
31
  R.merge(initialContext),
46
32
  R.zipObj(contextSettersNames),
47
33
  R.map(R.always(NOOP))
@@ -2,7 +2,6 @@
2
2
  import * as R from "ramda";
3
3
  import * as React from "react";
4
4
  import { Platform } from "react-native";
5
- import createRef from "create-react-ref/lib/createRef";
6
5
 
7
6
  import { addLifeCycleMethods, wrapInClass, isClassComponent } from "./helpers";
8
7
 
@@ -19,16 +18,6 @@ export function attachLifeCycleMethods(lifecycleMethods) {
19
18
  );
20
19
  }
21
20
 
22
- /**
23
- * creates a React Ref. if the version of React doesn't
24
- * have this API, will use a polyfill instead
25
- */
26
- export function createReactRef() {
27
- return React.createRef && typeof React.createRef === "function"
28
- ? React.createRef()
29
- : createRef();
30
- }
31
-
32
21
  /**
33
22
  * Clone the children and merge each of the cloned elements with otherProps.
34
23
  * @param {React.Children} children to clone
@@ -1,27 +0,0 @@
1
- jest.mock("create-react-context", () =>
2
- jest.fn(() => ({
3
- Consumer: jest.fn(),
4
- Provider: jest.fn(),
5
- }))
6
- );
7
-
8
- jest.mock("react", () => ({
9
- ...jest.requireActual("react"),
10
- createContext: undefined,
11
- }));
12
-
13
- const { createContext } = require("../index");
14
- const createReactContext = require("create-react-context");
15
-
16
- describe("when react context api is not defined", () => {
17
- it("uses the polyfill", () => {
18
- createContext({ foo: "bar" });
19
-
20
- expect(createReactContext).toHaveBeenCalledWith(
21
- expect.objectContaining({
22
- foo: "bar",
23
- setFoo: expect.any(Function),
24
- })
25
- );
26
- });
27
- });