@applicaster/zapp-react-native-utils 13.0.0-alpha.1436249127 → 13.0.0-alpha.1486614302

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 (139) hide show
  1. package/README.md +0 -10
  2. package/actionsExecutor/ActionExecutor.ts +16 -9
  3. package/actionsExecutor/ActionExecutorContext.tsx +159 -10
  4. package/alertUtils/alert.ts +148 -0
  5. package/alertUtils/index.ts +1 -148
  6. package/analyticsUtils/AnalyticPlayerListener.ts +18 -1
  7. package/analyticsUtils/__tests__/__snapshots__/analyticsManagerNoModule.test.js.snap +9 -9
  8. package/analyticsUtils/currentScreenProperities.ts +6 -4
  9. package/analyticsUtils/helpers/hooks.ts +1 -1
  10. package/appUtils/HooksManager/Hook.ts +6 -2
  11. package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +7 -7
  12. package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +186 -186
  13. package/appUtils/HooksManager/index.ts +3 -1
  14. package/appUtils/HooksManager/types.ts +5 -2
  15. package/appUtils/accessibilityManager/index.ts +42 -1
  16. package/appUtils/contextKeysManager/contextResolver.ts +66 -0
  17. package/appUtils/contextKeysManager/index.ts +2 -2
  18. package/appUtils/contextKeysManager/utils/index.ts +2 -1
  19. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +8 -6
  20. package/appUtils/focusManager/index.ts +24 -12
  21. package/appUtils/focusManagerAux/utils/index.ts +4 -3
  22. package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +2 -2
  23. package/appUtils/keyCodes/__tests__/keyCodes.test.js +1 -1
  24. package/appUtils/keyCodes/index.ts +11 -7
  25. package/appUtils/keyCodes/keys/keysByPlatform.ts +4 -0
  26. package/appUtils/keyInputHandler/KeyInputHandler.ts +68 -0
  27. package/appUtils/orientationHelper.ts +11 -13
  28. package/appUtils/platform/const.ts +14 -0
  29. package/appUtils/platform/platformUtils.ts +47 -4
  30. package/appUtils/playerManager/index.ts +1 -1
  31. package/appUtils/playerManager/player.ts +42 -18
  32. package/appUtils/playerManager/playerNative.ts +18 -2
  33. package/appUtils/playerManager/usePlayerControllerSetup.tsx +3 -3
  34. package/arrayUtils/__tests__/__snapshots__/arrayUtils.test.ts.snap +4 -4
  35. package/dateUtils/index.ts +2 -0
  36. package/equalUtils/__tests__/isEqual/combination.test.ts +263 -0
  37. package/equalUtils/index.ts +49 -30
  38. package/focusManager/FocusManager.ts +14 -2
  39. package/focusManager/index.ts +23 -4
  40. package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +4 -4
  41. package/functionUtils/index.ts +46 -8
  42. package/idleUtils/__tests__/withTimeout$.test.ts +37 -0
  43. package/idleUtils/index.ts +1 -1
  44. package/idleUtils/withTimeout.ts +15 -2
  45. package/index.d.ts +0 -12
  46. package/logger/const.ts +9 -67
  47. package/manifestUtils/__tests__/createConfig.test.js +16 -16
  48. package/manifestUtils/defaultManifestConfigurations/player.js +14 -0
  49. package/manifestUtils/fonts/index.js +5 -6
  50. package/manifestUtils/sharedConfiguration/screenPicker/__tests__/utils.test.js +304 -0
  51. package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +875 -0
  52. package/manifestUtils/sharedConfiguration/screenPicker/utils.js +130 -0
  53. package/modalState/__tests__/index.test.ts +51 -0
  54. package/modalState/index.ts +32 -2
  55. package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +6 -6
  56. package/navigationUtils/__tests__/itemTypes.test.js +2 -2
  57. package/navigationUtils/__tests__/navigationUtils.test.js +2 -2
  58. package/navigationUtils/index.ts +3 -3
  59. package/numberUtils/__tests__/toPositiveNumberWithDefault.test.ts +23 -3
  60. package/numberUtils/index.ts +11 -5
  61. package/package.json +5 -10
  62. package/playerUtils/configurationGenerator.ts +14 -0
  63. package/reactHooks/advertising/index.ts +5 -5
  64. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  65. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +6 -8
  66. package/reactHooks/autoscrolling/useTrackedView.ts +12 -1
  67. package/reactHooks/cell-click/__tests__/index.test.js +10 -2
  68. package/reactHooks/cell-click/index.ts +7 -1
  69. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +4 -4
  70. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +10 -11
  71. package/reactHooks/feed/useFeedLoader.tsx +5 -3
  72. package/reactHooks/feed/usePipesCacheReset.ts +5 -5
  73. package/reactHooks/flatList/__tests__/index.test.tsx +30 -21
  74. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +39 -0
  75. package/reactHooks/layout/__tests__/index.test.tsx +10 -10
  76. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +14 -28
  77. package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +1 -1
  78. package/reactHooks/layout/useDimensions/useDimensions.ts +8 -0
  79. package/reactHooks/navigation/__mocks__/useNavigation.ts +3 -0
  80. package/reactHooks/navigation/__tests__/index.test.tsx +6 -21
  81. package/reactHooks/navigation/index.ts +34 -236
  82. package/reactHooks/navigation/useGetBottomTabBarHeight.ts +12 -0
  83. package/reactHooks/navigation/useGetNavBarTopBorderWidth.ts +14 -0
  84. package/reactHooks/navigation/useGetTabBarHeight.ts +10 -0
  85. package/reactHooks/navigation/useIsScreenActive.ts +17 -0
  86. package/reactHooks/navigation/useNavigationPluginData.ts +15 -0
  87. package/reactHooks/navigation/useNavigationType.ts +15 -0
  88. package/reactHooks/navigation/usePathname.ts +4 -0
  89. package/reactHooks/navigation/useProfilerLogging.ts +15 -0
  90. package/reactHooks/navigation/useRoute.ts +98 -0
  91. package/reactHooks/navigation/useUniqueRouteSuffix.ts +41 -0
  92. package/reactHooks/player/TVSeekControlller/ISeekController.ts +32 -0
  93. package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +71 -0
  94. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +258 -0
  95. package/reactHooks/player/TVSeekControlller/TapSeekController.ts +53 -0
  96. package/reactHooks/player/__tests__/{useAutoSeek.test.tsx → useAutoSeek._test.tsx} +2 -3
  97. package/reactHooks/player/const.ts +0 -4
  98. package/reactHooks/player/index.ts +0 -6
  99. package/reactHooks/state/useRefWithInitialValue.ts +14 -0
  100. package/reactHooks/state/useStateFromSubscribe.ts +23 -0
  101. package/reactHooks/usePluginConfiguration.ts +1 -1
  102. package/reactHooks/useSubscriberFor.ts +4 -3
  103. package/reactUtils/__tests__/__snapshots__/reactUtilsHelpers.test.js.snap +16 -4
  104. package/reactUtils/__tests__/reactUtils.test.js +1 -37
  105. package/reactUtils/__tests__/reactUtilsHelpers.test.js +72 -71
  106. package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +13 -79
  107. package/reactUtils/createContext/__tests__/__snapshots__/{index.test.js.snap → index.test.ts.snap} +2 -2
  108. package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -28
  109. package/reactUtils/createContext/__tests__/__snapshots__/withConsumer.test.js.snap +3 -4
  110. package/reactUtils/createContext/__tests__/__snapshots__/withProvider.test.js.snap +7 -3
  111. package/reactUtils/createContext/__tests__/helpers.test.js +107 -121
  112. package/reactUtils/createContext/__tests__/{index.test.js → index.test.ts} +2 -2
  113. package/reactUtils/createContext/__tests__/provider.test.js +4 -6
  114. package/reactUtils/createContext/__tests__/withConsumer.test.js +12 -12
  115. package/reactUtils/createContext/__tests__/withProvider.test.js +4 -4
  116. package/reactUtils/createContext/helpers.ts +6 -1
  117. package/reactUtils/createContext/index.ts +11 -25
  118. package/reactUtils/index.ts +0 -11
  119. package/screenState/index.ts +24 -10
  120. package/services/js2native.ts +673 -0
  121. package/testUtils/index.tsx +0 -10
  122. package/theme/__mocks__/index.ts +4 -0
  123. package/theme/index.ts +1 -1
  124. package/time/BackgroundTimer.ts +55 -0
  125. package/time/Timer.ts +9 -6
  126. package/types.ts +1 -0
  127. package/utils/README.md +30 -0
  128. package/utils/chunk.ts +5 -0
  129. package/utils/index.ts +17 -0
  130. package/utils/times.ts +5 -0
  131. package/zappFrameworkUtils/localStorageHelper.ts +6 -0
  132. package/zappFrameworkUtils/loginPluginUtils.ts +6 -2
  133. package/zappFrameworkUtils/presentPluginOneTime.ts +2 -3
  134. package/zappFrameworkUtils/types.ts +11 -0
  135. package/reactHooks/player/useAutoSeek.tsx +0 -87
  136. package/reactHooks/player/useSeek.tsx +0 -66
  137. package/reactHooks/player/useTapSeek.tsx +0 -58
  138. package/reactUtils/createContext/__tests__/index-no-react.test.js +0 -27
  139. /package/reactHooks/player/__tests__/{useTapSeek.test.ts → useTapSeek._test.ts} +0 -0
@@ -0,0 +1,258 @@
1
+ import { BehaviorSubject } from "rxjs";
2
+ import { TapSeekController } from "./TapSeekController";
3
+ import { LongPressSeekController } from "./LongPressSeekController";
4
+ import { SEEK_TYPE } from "../const";
5
+ import { createLogger } from "../../../logger";
6
+ import { Player } from "../../../appUtils/playerManager/player";
7
+ import { SeekKeyHandlerListener } from "../../../appUtils/keyInputHandler/KeyInputHandler";
8
+ import {
9
+ ISeekController,
10
+ ISeekControllerDelegate,
11
+ SeekIncrementalBaseStrategy,
12
+ } from "./ISeekController";
13
+
14
+ export const { log_warning, log_debug, log_info, log_error, log_verbose } =
15
+ createLogger({
16
+ category: "General",
17
+ subsystem: "TVSeekController",
18
+ });
19
+
20
+ export enum SEEK_STRATEGY {
21
+ TAP_SEEK = "TAP_SEEK",
22
+ AUTO_SEEK = "AUTO_SEEK",
23
+ }
24
+
25
+ const CONFIG_TAP_SEEK = {
26
+ CLICKS_BEFORE_PAUSE: 0,
27
+ };
28
+
29
+ const CONFIG_LONG_PRESS = {
30
+ TIMER_INTERVAL_MS: 200,
31
+ };
32
+
33
+ const LONG_PRESS_THRESHOLD = 500;
34
+ const SEEK_END_TIMEOUT_DURATION = 700;
35
+ // prettier-ignore
36
+
37
+ export class TVSeekController
38
+ implements SeekKeyHandlerListener, ISeekControllerDelegate {
39
+ public delayedSeekPosition: number | null = null;
40
+ private readonly playerController: Player;
41
+ private delayedSeekProgressSubject = new BehaviorSubject<number | null>(null);
42
+ isPlayerInitiallyPaused: null | boolean = null;
43
+ currentSeekType: SEEK_TYPE | null = null;
44
+
45
+ private currentSeekController: ISeekController;
46
+ private readonly tapSeekController: TapSeekController;
47
+ private readonly longPressSeekController: LongPressSeekController;
48
+ private longPressThresholdTimeout: any | null = null;
49
+ private seekEndTimeout: any | null = null;
50
+
51
+ constructor(playerController: Player) {
52
+ this.playerController = playerController;
53
+
54
+ this.tapSeekController = new TapSeekController(
55
+ this,
56
+ new SeekIncrementalBaseStrategy(),
57
+ CONFIG_TAP_SEEK
58
+ );
59
+
60
+ this.longPressSeekController = new LongPressSeekController(
61
+ this,
62
+ new SeekIncrementalBaseStrategy(),
63
+ CONFIG_LONG_PRESS
64
+ );
65
+
66
+ this.currentSeekController = this.tapSeekController;
67
+ }
68
+
69
+ getDelayedSeekProgressObservable = () => {
70
+ return this.delayedSeekProgressSubject;
71
+ };
72
+
73
+ setStrategy = (seekStrategy: SEEK_STRATEGY) => {
74
+ switch (seekStrategy) {
75
+ case SEEK_STRATEGY.TAP_SEEK:
76
+ this.currentSeekController = this.tapSeekController;
77
+ log_debug("TVSeekController: setStrategy - TAP_SEEK");
78
+
79
+ break;
80
+ case SEEK_STRATEGY.AUTO_SEEK:
81
+ this.currentSeekController = this.longPressSeekController;
82
+ log_debug("TVSeekController: setStrategy - AUTO_SEEK");
83
+
84
+ break;
85
+ default:
86
+ }
87
+ };
88
+
89
+ handleStartSeek = (seekType: SEEK_TYPE) => {
90
+ this.currentSeekType = seekType;
91
+
92
+ if (this.isPlayerInitiallyPaused === null) {
93
+ this.isPlayerInitiallyPaused = this.playerController.isPaused();
94
+ }
95
+
96
+ this.clearLongPressThresholdTimeout();
97
+ this.clearSeekCompleteTimeout();
98
+ this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
99
+ this.currentSeekController.onStartSeek(seekType);
100
+
101
+ this.longPressThresholdTimeout = setTimeout(() => {
102
+ this.setStrategy(SEEK_STRATEGY.AUTO_SEEK);
103
+ this.currentSeekController.onStartSeek(seekType);
104
+ }, LONG_PRESS_THRESHOLD);
105
+ };
106
+
107
+ onForwardPress = (): boolean => {
108
+ this.handleStartSeek(SEEK_TYPE.FORWARD);
109
+
110
+ return true;
111
+ };
112
+
113
+ onRewindPress = (): boolean => {
114
+ this.handleStartSeek(SEEK_TYPE.REWIND);
115
+
116
+ return true;
117
+ };
118
+
119
+ onSeekEnd = () => {
120
+ this.clearLongPressThresholdTimeout();
121
+ this.currentSeekController.onSeekEnd();
122
+ };
123
+
124
+ onRewindPressOut = () => {
125
+ this.onSeekEnd();
126
+ };
127
+
128
+ onForwardPressOut = () => {
129
+ this.onSeekEnd();
130
+ };
131
+
132
+ onVideoProgress = (position: number) => {
133
+ if (this.delayedSeekPosition !== null) {
134
+ return;
135
+ }
136
+
137
+ this.delayedSeekProgressSubject.next(position);
138
+ };
139
+
140
+ handleDelayedSeek = (offset: number = 0) => {
141
+ this.handlePlayerPause();
142
+
143
+ const currentPos =
144
+ this.delayedSeekPosition === null
145
+ ? this.playerController.getPosition()
146
+ : this.delayedSeekPosition;
147
+
148
+ let targetPos = currentPos;
149
+
150
+ if (this.currentSeekType === SEEK_TYPE.FORWARD) {
151
+ targetPos = Math.min(
152
+ currentPos + offset,
153
+ this.playerController.getSeekableDuration()
154
+ );
155
+ } else if (this.currentSeekType === SEEK_TYPE.REWIND) {
156
+ targetPos = Math.max(0, currentPos - offset);
157
+ } else {
158
+ log_warning(
159
+ `TVSeekController: handleDelayedSeek - invalid seek type: ${this.currentSeekType}`
160
+ );
161
+ }
162
+
163
+ log_debug(
164
+ `TVSeekController: handleDelayedSeek - targetPos: ${targetPos}, skipTime: ${offset}`
165
+ );
166
+
167
+ const prevValue = this.delayedSeekProgressSubject.getValue();
168
+
169
+ if (prevValue !== null) {
170
+ const delta = Math.abs(prevValue - targetPos);
171
+
172
+ if (delta < 1) {
173
+ return;
174
+ }
175
+ }
176
+
177
+ this.delayedSeekPosition = targetPos;
178
+ this.delayedSeekProgressSubject.next(targetPos);
179
+ };
180
+
181
+ handleSeekTo = (newPosition: number) => {
182
+ this.playerController.seekTo(newPosition);
183
+
184
+ if (!this.isPlayerInitiallyPaused) {
185
+ this.playerController.play();
186
+ }
187
+ };
188
+
189
+ handleSeek = (offset: number) => {
190
+ this.playerController[this.currentSeekType](offset);
191
+
192
+ if (!this.isPlayerInitiallyPaused) {
193
+ this.playerController.play();
194
+ }
195
+ };
196
+
197
+ handleSeekComplete = () => {
198
+ this.clearSeekCompleteTimeout();
199
+
200
+ this.seekEndTimeout = setTimeout(() => {
201
+ if (this.delayedSeekPosition !== null) {
202
+ this.handleSeekTo(this.delayedSeekPosition);
203
+ }
204
+
205
+ log_debug(
206
+ `handleSeekComplete: Seek finished, type: ${this.currentSeekController.title}, seekPosition: ${this.delayedSeekPosition}. Reset all states and seek position.`
207
+ );
208
+
209
+ this.resetAll();
210
+ }, SEEK_END_TIMEOUT_DURATION);
211
+ };
212
+
213
+ isSeeking = (): boolean => {
214
+ return this.delayedSeekPosition !== null;
215
+ };
216
+
217
+ handlePlayerPause = () => {
218
+ if (this.playerController.isPaused()) {
219
+ return;
220
+ }
221
+
222
+ this.playerController.pause();
223
+ };
224
+
225
+ clearSeekCompleteTimeout = () => {
226
+ if (this.seekEndTimeout === null) {
227
+ return;
228
+ }
229
+
230
+ clearTimeout(this.seekEndTimeout);
231
+ this.seekEndTimeout = null;
232
+ };
233
+
234
+ clearLongPressThresholdTimeout = () => {
235
+ if (this.longPressThresholdTimeout === null) {
236
+ return;
237
+ }
238
+
239
+ clearTimeout(this.longPressThresholdTimeout);
240
+ this.longPressThresholdTimeout = null;
241
+ };
242
+
243
+ resetAll() {
244
+ log_debug("TVSeekController: Reset all states");
245
+ this.currentSeekType = null;
246
+
247
+ this.delayedSeekPosition = null;
248
+ this.isPlayerInitiallyPaused = null;
249
+
250
+ this.clearSeekCompleteTimeout();
251
+ this.clearLongPressThresholdTimeout();
252
+
253
+ this.tapSeekController.reset();
254
+ this.longPressSeekController.reset();
255
+
256
+ this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
257
+ }
258
+ }
@@ -0,0 +1,53 @@
1
+ import {
2
+ ISeekController,
3
+ ISeekControllerDelegate,
4
+ SeekIncrementalBaseStrategy,
5
+ } from "./ISeekController";
6
+ import { SEEK_TYPE } from "../const";
7
+ import { log_debug } from "./TVSeekController";
8
+
9
+ interface TapPressConfig {
10
+ CLICKS_BEFORE_PAUSE: number;
11
+ }
12
+
13
+ export class TapSeekController implements ISeekController {
14
+ readonly title = "TapSeek";
15
+ constructor(
16
+ private seekControllerDelegate: ISeekControllerDelegate,
17
+ private seekIncrementalStrategy: SeekIncrementalBaseStrategy,
18
+ private config: TapPressConfig
19
+ ) {}
20
+
21
+ onStartSeek = (seekType: SEEK_TYPE) => {
22
+ log_debug(`${this.title}: start tap seek type: ${seekType}.`);
23
+
24
+ const skipTime = this.seekIncrementalStrategy.getSkipTime();
25
+ const seekMultiplier = this.seekIncrementalStrategy.getSkipMultiplier();
26
+
27
+ if (seekMultiplier > this.config.CLICKS_BEFORE_PAUSE) {
28
+ log_debug(
29
+ `${this.title}: handle delayed seek type:${seekType} - skipTime: ${skipTime}, seekMultiplier: ${seekMultiplier}.`
30
+ );
31
+
32
+ this.seekControllerDelegate.handleDelayedSeek(skipTime);
33
+ } else {
34
+ log_debug(
35
+ `${this.title}: handle seek type:${seekType} - skipTime: ${skipTime}.`
36
+ );
37
+
38
+ this.seekControllerDelegate.handleSeek(skipTime);
39
+ }
40
+
41
+ this.seekIncrementalStrategy.increment();
42
+ };
43
+
44
+ onSeekEnd = () => {
45
+ this.seekControllerDelegate.handleSeekComplete();
46
+ };
47
+
48
+ reset = () => {
49
+ log_debug("{this.title}: Reset states");
50
+
51
+ this.seekIncrementalStrategy.reset();
52
+ };
53
+ }
@@ -5,15 +5,14 @@ import { ON_HOLD_INTERVAL, SEEK_TYPE, SKIP_TIME_BASE } from "../const";
5
5
 
6
6
  import { useAutoSeek } from "../useAutoSeek";
7
7
 
8
- jest.useFakeTimers();
8
+ jest.useFakeTimers({ legacyFakeTimers: true });
9
9
 
10
10
  const rewind = jest.fn();
11
11
  const forward = jest.fn();
12
12
 
13
13
  jest
14
14
  .spyOn(playerManager, "getInstanceController")
15
- // @ts-ignore
16
- .mockImplementation(() => ({ rewind, forward }));
15
+ .mockReturnValue({ rewind, forward });
17
16
 
18
17
  describe("useAutoSeek", () => {
19
18
  beforeEach(() => {
@@ -1,9 +1,5 @@
1
1
  export const SKIP_TIME_BASE = 10;
2
2
 
3
- export const ON_PRESS_RESET_DURATION = 2000;
4
-
5
- export const ON_HOLD_INTERVAL = 500;
6
-
7
3
  export const MAX_SEEK_TIME = 600;
8
4
 
9
5
  export enum SEEK_TYPE {
@@ -1,7 +1 @@
1
1
  export { useLanguageData } from "./useLanguageData";
2
-
3
- export { useAutoSeek } from "./useAutoSeek";
4
-
5
- export { useTapSeek } from "./useTapSeek";
6
-
7
- export { useSeek, withUseSeek } from "./useSeek";
@@ -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,6 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`addLifeCycleMethods attaches the lifecycle method to the component 1`] = `
3
+ exports[`reactUtils helpers addLifeCycleMethods attaches the lifecycle method to the component 1`] = `
4
4
  <View>
5
5
  <Text>
6
6
  I'm a class component
@@ -8,7 +8,7 @@ exports[`addLifeCycleMethods attaches the lifecycle method to the component 1`]
8
8
  </View>
9
9
  `;
10
10
 
11
- exports[`attachMethodToPrototype attaches a lifecycle method to the component's prototype 1`] = `
11
+ exports[`reactUtils helpers attachMethodToPrototype attaches a lifecycle method to the component's prototype 1`] = `
12
12
  <View>
13
13
  <Text>
14
14
  I'm a class component
@@ -16,6 +16,18 @@ exports[`attachMethodToPrototype attaches a lifecycle method to the component's
16
16
  </View>
17
17
  `;
18
18
 
19
- exports[`attachMethodToPrototype preserves any existing lifecycle method 1`] = `<StatelessComponent />`;
19
+ exports[`reactUtils helpers attachMethodToPrototype preserves any existing lifecycle method 1`] = `
20
+ <View>
21
+ <Text>
22
+ I'm a stateless component
23
+ </Text>
24
+ </View>
25
+ `;
20
26
 
21
- exports[`wrapInClass wraps the stateless component in a class 1`] = `<StatelessComponent />`;
27
+ exports[`reactUtils helpers wrapInClass wraps the stateless component in a class 1`] = `
28
+ <View>
29
+ <Text>
30
+ I'm a stateless component
31
+ </Text>
32
+ </View>
33
+ `;
@@ -1,4 +1,3 @@
1
- jest.mock("create-react-ref/lib/createRef", () => jest.fn());
2
1
  import * as React from "react";
3
2
  import * as helpers from "../helpers";
4
3
 
@@ -8,13 +7,7 @@ import {
8
7
  componentDidMount,
9
8
  } from "./fixtures";
10
9
 
11
- const {
12
- attachLifeCycleMethods,
13
- createReactRef,
14
- mergeChildrenProps,
15
- } = require("../index");
16
-
17
- const createRef = require("create-react-ref/lib/createRef");
10
+ import { attachLifeCycleMethods, mergeChildrenProps } from "..";
18
11
 
19
12
  describe("attachLifeCycleMethods", () => {
20
13
  let addLifeCycleMethodsSpy;
@@ -48,35 +41,6 @@ describe("attachLifeCycleMethods", () => {
48
41
  });
49
42
  });
50
43
 
51
- describe("createReactRef", () => {
52
- it("calls the React.createRef function if it exists", () => {
53
- jest.resetModules();
54
-
55
- jest.doMock("react", () => ({
56
- ...jest.requireActual("react"),
57
- createRef: jest.fn(),
58
- }));
59
-
60
- const React = require("react");
61
-
62
- createReactRef();
63
- expect(React.createRef).toHaveBeenCalled();
64
- expect(createRef).not.toHaveBeenCalled();
65
- });
66
-
67
- it("calls the polyfill if React.createRef doesn't exist", () => {
68
- jest.resetModules();
69
-
70
- jest.doMock("react", () => ({
71
- ...jest.requireActual("react"),
72
- createRef: undefined,
73
- }));
74
-
75
- createReactRef();
76
- expect(createRef).toHaveBeenCalled();
77
- });
78
- });
79
-
80
44
  describe("mergeChildrenProps", () => {
81
45
  it("returns the cloned children with the merged props", () => {
82
46
  const Egg = () => React.createElement("Egg");
@@ -1,6 +1,5 @@
1
1
  import * as React from "react";
2
- import { shallow } from "enzyme";
3
- import { shallowToJson } from "enzyme-to-json";
2
+ import { render } from "@testing-library/react-native";
4
3
 
5
4
  import {
6
5
  isClassComponent,
@@ -20,98 +19,100 @@ import {
20
19
  } from "./fixtures";
21
20
 
22
21
  describe("reactUtils helpers", () => {
23
- it("should have isNilOrEmpty", () => {
24
- expect(isNilOrEmpty).toBeDefined();
25
- expect(isNilOrEmpty(null)).toBeTruthy();
26
- expect(isNilOrEmpty(undefined)).toBeTruthy();
27
- expect(isNilOrEmpty("")).toBeTruthy();
28
- expect(isNilOrEmpty([])).toBeTruthy();
22
+ describe("isNilOrEmpty", () => {
23
+ it("should return correct output", () => {
24
+ expect(isNilOrEmpty).toBeDefined();
25
+ expect(isNilOrEmpty(null)).toBeTruthy();
26
+ expect(isNilOrEmpty(undefined)).toBeTruthy();
27
+ expect(isNilOrEmpty("")).toBeTruthy();
28
+ expect(isNilOrEmpty([])).toBeTruthy();
29
+ });
29
30
  });
30
- });
31
31
 
32
- describe("isClassComponent", () => {
33
- it("returns true if the component is a class component", () => {
34
- expect(isClassComponent(ClassComponent)).toBe(true);
35
- });
32
+ describe("isClassComponent", () => {
33
+ it("returns true if the component is a class component", () => {
34
+ expect(isClassComponent(ClassComponent)).toBe(true);
35
+ });
36
36
 
37
- it("returns false otherwise", () => {
38
- expect(isClassComponent(StatelessComponent)).toBe(false);
37
+ it("returns false otherwise", () => {
38
+ expect(isClassComponent(StatelessComponent)).toBe(false);
39
+ });
39
40
  });
40
- });
41
41
 
42
- describe("attachMethodToPrototype", () => {
43
- const initialWrapper = shallow(<ClassComponent />);
42
+ describe("attachMethodToPrototype", () => {
43
+ const initialWrapper = render(<ClassComponent />);
44
44
 
45
- expect(initialWrapper.instance()).not.toHaveProperty(
46
- COMPONENT_DID_MOUNT_METHOD
47
- );
48
-
49
- afterEach(() => {
50
- componentDidMount.mockClear();
51
- });
52
-
53
- it("attaches a lifecycle method to the component's prototype", () => {
54
- const NewComponent = attachMethodToPrototype(ClassComponent)(
55
- componentDidMount,
45
+ expect(initialWrapper.toJSON()).not.toHaveProperty(
56
46
  COMPONENT_DID_MOUNT_METHOD
57
47
  );
58
48
 
59
- const wrapper = shallow(<NewComponent />);
49
+ afterEach(() => {
50
+ componentDidMount.mockClear();
51
+ });
60
52
 
61
- expect(shallowToJson(wrapper)).toMatchSnapshot();
62
- expect(wrapper.instance()).toHaveProperty(COMPONENT_DID_MOUNT_METHOD);
63
- expect(componentDidMount).toHaveBeenCalled();
64
- });
53
+ it("attaches a lifecycle method to the component's prototype", () => {
54
+ const NewComponent = attachMethodToPrototype(ClassComponent)(
55
+ componentDidMount,
56
+ COMPONENT_DID_MOUNT_METHOD
57
+ );
65
58
 
66
- it("preserves any existing lifecycle method", () => {
67
- const NewComponent = attachMethodToPrototype(ComponentWithLifeCycle)(
68
- componentDidMount,
69
- COMPONENT_DID_MOUNT_METHOD
70
- );
59
+ const wrapper = render(<NewComponent />);
71
60
 
72
- expect(componentDidMount).not.toHaveBeenCalled();
61
+ expect(wrapper.toJSON(wrapper)).toMatchSnapshot();
62
+ expect(new NewComponent()).toHaveProperty(COMPONENT_DID_MOUNT_METHOD);
63
+ expect(componentDidMount).toHaveBeenCalled();
64
+ });
73
65
 
74
- const wrapper = shallow(<NewComponent />);
66
+ it("preserves any existing lifecycle method", () => {
67
+ const NewComponent = attachMethodToPrototype(ComponentWithLifeCycle)(
68
+ componentDidMount,
69
+ COMPONENT_DID_MOUNT_METHOD
70
+ );
75
71
 
76
- expect(shallowToJson(wrapper)).toMatchSnapshot();
77
- expect(componentDidMount).toHaveBeenCalled();
78
- expect(existingMethod).toHaveBeenCalled();
79
- });
80
- });
72
+ expect(componentDidMount).not.toHaveBeenCalled();
81
73
 
82
- describe("wrapInClass", () => {
83
- let NewComponent;
84
- let wrapper;
74
+ const wrapper = render(<NewComponent />);
85
75
 
86
- beforeEach(() => {
87
- NewComponent = wrapInClass(StatelessComponent);
88
- wrapper = shallow(<NewComponent />);
76
+ expect(wrapper.toJSON()).toMatchSnapshot();
77
+ expect(componentDidMount).toHaveBeenCalled();
78
+ expect(existingMethod).toHaveBeenCalled();
79
+ });
89
80
  });
90
81
 
91
- it("wraps the stateless component in a class", () => {
92
- expect(isClassComponent(NewComponent)).toBe(true);
93
- expect(shallowToJson(wrapper)).toMatchSnapshot();
94
- });
95
- });
82
+ describe("wrapInClass", () => {
83
+ let NewComponent;
84
+ let wrapper;
96
85
 
97
- describe("addLifeCycleMethods", () => {
98
- let NewComponent;
99
- let wrapper;
86
+ beforeEach(() => {
87
+ NewComponent = wrapInClass(StatelessComponent);
88
+ wrapper = render(<NewComponent />);
89
+ });
100
90
 
101
- beforeEach(() => {
102
- NewComponent = addLifeCycleMethods({ componentDidMount })(ClassComponent);
103
- wrapper = shallow(<NewComponent />);
91
+ it("wraps the stateless component in a class", () => {
92
+ expect(isClassComponent(NewComponent)).toBe(true);
93
+ expect(wrapper.toJSON()).toMatchSnapshot();
94
+ });
104
95
  });
105
96
 
106
- afterEach(() => {
107
- componentDidMount.mockClear();
108
- });
97
+ describe("addLifeCycleMethods", () => {
98
+ let NewComponent;
99
+ let wrapper;
109
100
 
110
- it("attaches the lifecycle method to the component", () => {
111
- expect(shallowToJson(wrapper)).toMatchSnapshot();
112
- });
101
+ beforeEach(() => {
102
+ NewComponent = addLifeCycleMethods({ componentDidMount })(ClassComponent);
103
+ wrapper = render(<NewComponent />);
104
+ });
105
+
106
+ afterEach(() => {
107
+ componentDidMount.mockClear();
108
+ });
109
+
110
+ it("attaches the lifecycle method to the component", () => {
111
+ expect(wrapper.toJSON()).toMatchSnapshot();
112
+ });
113
113
 
114
- it("adds the lifecycle method to the component", () => {
115
- expect(componentDidMount).toHaveBeenCalled();
114
+ it("adds the lifecycle method to the component", () => {
115
+ expect(componentDidMount).toHaveBeenCalled();
116
+ });
116
117
  });
117
118
  });