@applicaster/zapp-react-native-utils 13.0.0-alpha.2761483533 → 13.0.0-alpha.3193563717

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.
@@ -16,7 +16,7 @@ const BASE_HOOK_PROPERTIES = ["screen_id", "identifier", "weight"];
16
16
  * @returns {number} index
17
17
  */
18
18
  const hookState: (
19
- arg0: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS]
19
+ arg0: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS]
20
20
  ) => number = R.indexOf(R.__, R.values(HOOKS_EVENTS));
21
21
 
22
22
  /**
@@ -62,7 +62,7 @@ export class Hook implements HookInterface {
62
62
  * @param {Array<Any>} args variadic arguments to invoke the handler with
63
63
  */
64
64
  setStateAndNotify(
65
- event: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS],
65
+ event: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS],
66
66
  ...args
67
67
  ) {
68
68
  this.state = hookState(event);
@@ -103,7 +103,7 @@ export interface Hook<T extends HookModule = HookModule> {
103
103
  identifier: string;
104
104
  configuration: T["configuration"];
105
105
  setStateAndNotify(
106
- event: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS],
106
+ event: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS],
107
107
  opts: {
108
108
  error?: typeof Error;
109
109
  route?: string;
@@ -112,7 +112,7 @@ export interface Hook<T extends HookModule = HookModule> {
112
112
  }
113
113
  );
114
114
  general?: {
115
- transition_type: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS];
115
+ transition_type: (typeof HOOKS_EVENTS)[keyof typeof HOOKS_EVENTS];
116
116
  allow_screen_plugin_presentation: boolean;
117
117
  is_flow_blocker: boolean;
118
118
  };
@@ -42,12 +42,16 @@ export const resolveObjectValues = async (
42
42
 
43
43
  const resolvedEntries = await Promise.all(
44
44
  entries.map(async ([key, value]) => {
45
- const regex = /@{([^/]+)\/([^}]*)}/;
46
-
47
45
  if (typeof value !== "string") {
48
46
  return [key, value];
49
47
  }
50
48
 
49
+ if (!value.startsWith("@")) {
50
+ return [key, value];
51
+ }
52
+
53
+ const regex = /@{([^/]+)\/([^}]*)}/;
54
+
51
55
  const match = (value as string).match(regex);
52
56
 
53
57
  if (match) {
@@ -28,6 +28,7 @@ exports[`focusManager should be defined 1`] = `
28
28
  "moveFocus": [Function],
29
29
  "on": [Function],
30
30
  "press": [Function],
31
+ "pressIn": [Function],
31
32
  "pressOut": [Function],
32
33
  "recoverFocus": [Function],
33
34
  "register": [Function],
@@ -326,8 +326,6 @@ export const focusManager = (function () {
326
326
  },
327
327
  });
328
328
 
329
- currentFocusNode = focusCandidate;
330
-
331
329
  focusableItem && setFocus(focusCandidate.id, null);
332
330
 
333
331
  return { success: true };
@@ -347,6 +345,14 @@ export const focusManager = (function () {
347
345
  });
348
346
  }
349
347
 
348
+ function pressIn() {
349
+ const currentFocusable = getCurrentFocus();
350
+
351
+ if (currentFocusable) {
352
+ currentFocusable.pressIn(null);
353
+ }
354
+ }
355
+
350
356
  /**
351
357
  * calls the `press` method on the current focus component
352
358
  * @public
@@ -554,6 +560,7 @@ export const focusManager = (function () {
554
560
  invokeHandler,
555
561
  removeHandler,
556
562
  longPress,
563
+ pressIn,
557
564
  pressOut,
558
565
  enableFocus,
559
566
  setInitialFocus,
@@ -77,13 +77,22 @@ export class ClosedCaptioningManager {
77
77
 
78
78
  private constructor() {
79
79
  this.initialize();
80
+
81
+ window["vizioDebug"] = {
82
+ setCCEnabled: (isCCEnabled: boolean) => {
83
+ this.ccState$.next(isCCEnabled);
84
+ },
85
+ };
80
86
  }
81
87
 
82
88
  static getInstance(): ClosedCaptioningManager {
83
89
  if (!ClosedCaptioningManager.ccManagerInstance) {
90
+ log_debug("ClosedCaptioningManager: Creating new instance");
84
91
  ClosedCaptioningManager.ccManagerInstance = new ClosedCaptioningManager();
85
92
  }
86
93
 
94
+ log_debug("ClosedCaptioningManager: Returning existing instance");
95
+
87
96
  return ClosedCaptioningManager.ccManagerInstance;
88
97
  }
89
98
 
@@ -92,23 +101,41 @@ export class ClosedCaptioningManager {
92
101
  PLATFORM_KEYS.deviceClosedCaptioningEnabled
93
102
  );
94
103
 
95
- log_debug("Initializing closed captioning manager", { existingState });
96
-
97
104
  if (existingState !== null) {
105
+ log_debug(
106
+ `ClosedCaptioningManager: Setting initial state to ${existingState}`
107
+ );
108
+
98
109
  this.ccState$.next(existingState === "true" || existingState === true);
110
+ } else {
111
+ log_debug("ClosedCaptioningManager: No existing state found");
99
112
  }
100
113
 
101
114
  if (hasVizioAPIs()) {
115
+ log_debug("ClosedCaptioningManager: Setting closed captioning handler");
116
+
102
117
  window.VIZIO!.setClosedCaptionHandler((isCCEnabled) => {
103
- log_debug("CC state changed", { isCCEnabled });
118
+ log_debug(
119
+ "ClosedCaptioningManager: There was a change in the CC state",
120
+ { isCCEnabled }
121
+ );
104
122
 
105
123
  sessionStorage.setItem(
106
124
  PLATFORM_KEYS.deviceClosedCaptioningEnabled,
107
125
  isCCEnabled
108
126
  );
109
127
 
128
+ log_debug(
129
+ "ClosedCaptioningManager: Saved CC state to session storage",
130
+ { isCCEnabled }
131
+ );
132
+
110
133
  this.ccState$.next(isCCEnabled);
111
134
  });
135
+ } else {
136
+ log_debug(
137
+ "ClosedCaptioningManager: Vizio APIs are not available, skipping setup"
138
+ );
112
139
  }
113
140
  }
114
141
 
@@ -154,8 +154,8 @@ export class Player {
154
154
  this.isSeeking()
155
155
  ? this.playerState.seekPosition
156
156
  : this.playerState.adState
157
- ? this.playerState.adState.adPosition
158
- : this.playerState.contentPosition;
157
+ ? this.playerState.adState.adPosition
158
+ : this.playerState.contentPosition;
159
159
 
160
160
  getEntry = (): ZappEntry | null => this.entry;
161
161
 
@@ -78,8 +78,6 @@ describe("createConfig", () => {
78
78
  extend: "styles",
79
79
  })(props);
80
80
 
81
- console.log(mockGenerators.styles.mock.calls);
82
-
83
81
  expect(mockGenerators.styles).toBeCalledWith(props);
84
82
  });
85
83
 
@@ -644,8 +644,8 @@ export const getScreenId = (
644
644
  fallbackRiver: ZappRiver
645
645
  ) => {
646
646
  return screenData?.targetScreen
647
- ? screenData?.targetScreen?.id ?? fallbackRiver.id
647
+ ? (screenData?.targetScreen?.id ?? fallbackRiver.id)
648
648
  : "screen_id" in screenData
649
- ? screenData.screen_id
650
- : fallbackRiver.id;
649
+ ? screenData.screen_id
650
+ : fallbackRiver.id;
651
651
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "13.0.0-alpha.2761483533",
3
+ "version": "13.0.0-alpha.3193563717",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "13.0.0-alpha.2761483533",
31
+ "@applicaster/applicaster-types": "13.0.0-alpha.3193563717",
32
32
  "buffer": "^5.2.1",
33
33
  "camelize": "^1.0.0",
34
34
  "create-react-context": "^0.2.3",
@@ -5,7 +5,7 @@ const mockDimensionsGet = jest.fn(
5
5
  ({
6
6
  window: { width: 1, height: 1 },
7
7
  screen: { width: 360, height: 540 },
8
- }[type])
8
+ })[type]
9
9
  );
10
10
 
11
11
  ReactNative.Dimensions.get = mockDimensionsGet;
@@ -52,6 +52,14 @@ export const useDimensions: UseDimensions = (
52
52
  ? { fullDimensions }
53
53
  : { ...fullDimensions };
54
54
 
55
+ if (options.updateForInactiveScreens === undefined) {
56
+ options.updateForInactiveScreens = true;
57
+ }
58
+
59
+ if (options.fullDimensions === undefined) {
60
+ options.fullDimensions = false;
61
+ }
62
+
55
63
  const [dimensions, setDimensions] = useState(getInitialDimensions(context));
56
64
  const deviceInfo = useRef(getDeviceInfo(dimensions, appData));
57
65
 
@@ -1,5 +1,3 @@
1
- import { useSafeAreaInsets } from "react-native-safe-area-context";
2
-
3
1
  import { platformSelect } from "../../reactUtils";
4
2
 
5
3
  const TAB_BAR_HEIGHT_IOS = 49;
@@ -7,6 +5,6 @@ const TAB_BAR_HEIGHT_ANDROID = 56;
7
5
 
8
6
  export const useGetTabBarHeight = () =>
9
7
  platformSelect({
10
- ios: TAB_BAR_HEIGHT_IOS + (useSafeAreaInsets().bottom ?? 0),
8
+ ios: TAB_BAR_HEIGHT_IOS,
11
9
  android: TAB_BAR_HEIGHT_ANDROID,
12
10
  }) as number;
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+
3
+ /**
4
+ * returns a ref with an initial value that is lazily evaluated once
5
+ * */
6
+ export const useRefWithInitialValue = <T>(initialValueGetter: () => T) => {
7
+ const ref = React.useRef<T>(null);
8
+
9
+ if (ref.current === null) {
10
+ ref.current = initialValueGetter();
11
+ }
12
+
13
+ return ref;
14
+ };
@@ -0,0 +1,23 @@
1
+ import { useEffect, useState } from "react";
2
+ import type { Subject } from "rxjs";
3
+
4
+ export const useStateFromSubscribe = <T, U>(
5
+ subject: Subject<T>,
6
+ onUpdate: (
7
+ observerValue: T,
8
+ next: React.Dispatch<React.SetStateAction<U>>
9
+ ) => void,
10
+ initialValue: U
11
+ ) => {
12
+ const [state, setState] = useState<U>(initialValue);
13
+
14
+ useEffect(() => {
15
+ const subscription = subject.subscribe((observer) =>
16
+ onUpdate(observer, setState)
17
+ );
18
+
19
+ return () => subscription.unsubscribe();
20
+ }, [subject]);
21
+
22
+ return state;
23
+ };
@@ -91,7 +91,7 @@ export function useLayoutConfiguration<
91
91
  S extends unknown,
92
92
  G extends unknown,
93
93
  R extends unknown,
94
- L extends unknown
94
+ L extends unknown,
95
95
  >(layoutData, manifest, options: Options = {}) {
96
96
  const keys = options.keys || [
97
97
  "assets",
@@ -4,9 +4,10 @@ import { subscriber } from "@applicaster/zapp-react-native-utils/functionUtils";
4
4
  const subscriberObjects = Object.create({});
5
5
 
6
6
  interface UseSubscriberFor {
7
- (eventName: string, handler?: (...args: unknown[]) => void): (
8
- ...args: unknown[]
9
- ) => ReturnType<typeof subscriber>;
7
+ (
8
+ eventName: string,
9
+ handler?: (...args: unknown[]) => void
10
+ ): (...args: unknown[]) => ReturnType<typeof subscriber>;
10
11
  }
11
12
 
12
13
  /**
@@ -1,6 +1,8 @@
1
1
  import { create } from "zustand";
2
2
  import { produce } from "immer";
3
3
  import { path } from "ramda";
4
+ import React from "react";
5
+ import { useShallow } from "zustand/react/shallow";
4
6
 
5
7
  type ScreenState = {
6
8
  selectedEntry: {
@@ -18,6 +20,8 @@ type ScreenStore = {
18
20
  setSelectedEntry: (screenId: string, entryId: string) => void;
19
21
  };
20
22
 
23
+ type SetSelectedEntry = (screenId: string, entryId: string) => void;
24
+
21
25
  const useScreenStore = create<ScreenStore>((set) => ({
22
26
  screens: screensInitialState,
23
27
  setSelectedEntry: (screenId, entryId) =>
@@ -35,17 +39,27 @@ const useScreenStore = create<ScreenStore>((set) => ({
35
39
  export function useScreenState(
36
40
  screenId: ScreenId
37
41
  ): null | { screen: ScreenState; setSelectedEntry: (entryId: string) => void } {
38
- // const state = useState(screenState);
39
- const screenState = useScreenStore(
40
- path(["screens", screenId])
41
- ) as ScreenState;
42
+ const screenState = useScreenStore<ScreenState>(
43
+ useShallow(path(["screens", screenId]))
44
+ );
42
45
 
43
- const setSelectedEntry = useScreenStore((state) => state.setSelectedEntry);
46
+ const setSelectedEntry = useScreenStore<SetSelectedEntry>(
47
+ useShallow(path(["setSelectedEntry"]))
48
+ );
44
49
 
45
- if (!screenId) return null;
50
+ const memoizedSetSelectedEntry = React.useCallback(
51
+ (entryId) => setSelectedEntry(screenId, entryId),
52
+ [screenId, setSelectedEntry]
53
+ );
46
54
 
47
- return {
48
- screen: screenState,
49
- setSelectedEntry: (entryId) => setSelectedEntry(screenId, entryId),
50
- };
55
+ return React.useMemo(
56
+ () =>
57
+ !screenId
58
+ ? null
59
+ : {
60
+ screen: screenState,
61
+ setSelectedEntry: memoizedSetSelectedEntry,
62
+ },
63
+ [screenId, screenState]
64
+ );
51
65
  }
package/theme/index.ts CHANGED
@@ -14,7 +14,7 @@ export const ThemeContext = React.createContext({
14
14
  export function useTheme<
15
15
  T extends Record<string, any> =
16
16
  | BaseThemePropertiesTV
17
- | BaseThemePropertiesMobile
17
+ | BaseThemePropertiesMobile,
18
18
  >(): T {
19
19
  const { themes, selectedThemeId } = React.useContext(ThemeContext);
20
20
 
package/time/Timer.ts CHANGED
@@ -3,7 +3,10 @@ export class Timer {
3
3
  private remaining: number;
4
4
  private timeoutId: NodeJS.Timeout | null;
5
5
 
6
- constructor(private callback: () => void, private duration: number) {
6
+ constructor(
7
+ private callback: () => void,
8
+ private duration: number
9
+ ) {
7
10
  this.remaining = this.duration;
8
11
  this.timeoutId = null;
9
12
  }
@@ -92,9 +92,8 @@ export const PresentHookPluginOneTime = (
92
92
  const presentOneTimeVersionName =
93
93
  await getLatestWatchedVersionNumberFromStorage(storageKey, namespace);
94
94
 
95
- const applicationVersionName = await sessionStorage.getItem(
96
- versionNameKey
97
- );
95
+ const applicationVersionName =
96
+ await sessionStorage.getItem(versionNameKey);
98
97
 
99
98
  if (!presentOneTimeVersionName || !applicationVersionName) {
100
99
  log_info(