@applicaster/zapp-react-native-utils 13.0.0-alpha.4515349201 → 13.0.0-alpha.4700935119
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.
- package/actionsExecutor/ActionExecutor.ts +16 -9
- package/actionsExecutor/ActionExecutorContext.tsx +74 -9
- package/alertUtils/alert.ts +148 -0
- package/alertUtils/index.ts +1 -148
- package/analyticsUtils/AnalyticPlayerListener.ts +18 -1
- package/analyticsUtils/__tests__/__snapshots__/analyticsManagerNoModule.test.js.snap +9 -9
- package/analyticsUtils/helpers/hooks.ts +1 -1
- package/appUtils/HooksManager/{Hook.js → Hook.ts} +35 -23
- package/appUtils/HooksManager/__tests__/__snapshots__/hook.test.js.snap +10 -8
- package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +693 -0
- package/appUtils/HooksManager/__tests__/hook.test.js +196 -184
- package/appUtils/HooksManager/__tests__/hooksManager.test.js +96 -99
- package/appUtils/HooksManager/{constants.js → constants.ts} +1 -1
- package/appUtils/HooksManager/{index.js → index.ts} +121 -112
- package/appUtils/HooksManager/types.ts +119 -0
- package/appUtils/RiverFocusManager/index.js +17 -12
- package/appUtils/accessibilityManager/index.ts +42 -1
- package/appUtils/contextKeysManager/contextResolver.ts +73 -0
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +6 -6
- package/appUtils/focusManager/index.ts +90 -63
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +25 -3
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +1 -3
- package/appUtils/focusManager/utils/enums.ts +4 -0
- package/appUtils/focusManagerAux/utils/index.ts +4 -3
- package/appUtils/{index.js → index.ts} +1 -1
- package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +2 -2
- package/appUtils/keyCodes/__tests__/keyCodes.test.js +4 -4
- package/appUtils/keyCodes/{index.js → index.ts} +2 -0
- package/appUtils/keyCodes/keys/index.ts +3 -0
- package/appUtils/keyCodes/{keys.android.js → keys/keyEventMapper.ts} +0 -19
- package/appUtils/keyCodes/keys/keys.android.ts +18 -0
- package/appUtils/keyCodes/keys/keys.ios.ts +25 -0
- package/appUtils/keyCodes/keys/keys.ts +15 -0
- package/appUtils/keyCodes/{keysByPlatform.js → keys/keysByPlatform.ts} +3 -3
- package/appUtils/keyCodes/keysByPlatform.ts +8 -0
- package/appUtils/orientationHelper.ts +1 -1
- package/appUtils/platform/const.ts +14 -0
- package/appUtils/platform/platformUtils.ts +17 -15
- package/appUtils/playerManager/playerNative.ts +1 -1
- package/arrayUtils/__tests__/__snapshots__/arrayUtils.test.ts.snap +4 -4
- package/domUtils/{cookieManager.js → cookieManager.ts} +1 -2
- package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +4 -4
- package/functionUtils/index.ts +15 -11
- package/logger/const.ts +9 -67
- package/manifestUtils/__tests__/createConfig.test.js +18 -16
- package/modalState/index.ts +1 -5
- package/navigationUtils/__tests__/__snapshots__/navigationUtils.test.js.snap +6 -6
- package/navigationUtils/__tests__/itemTypes.test.js +2 -2
- package/navigationUtils/__tests__/navigationUtils.test.js +2 -2
- package/navigationUtils/index.ts +14 -5
- package/package.json +3 -2
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -1
- package/reactHooks/cell-click/__tests__/index.test.js +10 -2
- package/reactHooks/cell-click/index.ts +7 -1
- package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +4 -4
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +10 -11
- package/reactHooks/feed/useFeedLoader.tsx +1 -1
- package/reactHooks/feed/usePipesCacheReset.ts +5 -5
- package/reactHooks/flatList/__tests__/index.test.tsx +30 -21
- package/reactHooks/layout/__tests__/index.test.tsx +10 -10
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +14 -28
- package/reactHooks/navigation/__tests__/index.test.tsx +0 -4
- package/reactHooks/navigation/index.ts +29 -218
- package/reactHooks/navigation/useGetBottomTabBarHeight.ts +12 -0
- package/reactHooks/navigation/useGetNavBarTopBorderWidth.ts +14 -0
- package/reactHooks/navigation/useGetTabBarHeight.ts +12 -0
- package/reactHooks/navigation/useIsScreenActive.ts +17 -0
- package/reactHooks/navigation/useNavigationPluginData.ts +15 -0
- package/reactHooks/navigation/useNavigationType.ts +15 -0
- package/reactHooks/navigation/usePathname.ts +4 -0
- package/reactHooks/navigation/useRoute.ts +100 -0
- package/reactHooks/navigation/useUniqueRouteSuffix.ts +41 -0
- package/reactHooks/player/TVSeekControlller/ISeekController.ts +19 -2
- package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +20 -41
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +80 -31
- package/reactHooks/player/TVSeekControlller/TapSeekController.ts +18 -40
- package/reactHooks/player/__tests__/useAutoSeek._test.tsx +115 -0
- package/reactHooks/player/__tests__/useTapSeek._test.ts +94 -0
- package/reactHooks/player/const.ts +1 -1
- package/reactUtils/__tests__/reactUtils.test.js +10 -28
- package/reactUtils/createContext/__tests__/__snapshots__/helpers.test.js.snap +19 -19
- package/reactUtils/createContext/__tests__/__snapshots__/index.test.js.snap +2 -2
- package/reactUtils/createContext/__tests__/__snapshots__/provider.test.js.snap +3 -3
- package/reactUtils/createContext/__tests__/helpers.test.js +8 -8
- package/reactUtils/index.ts +0 -14
- package/theme/__mocks__/index.ts +4 -0
- package/time/Timer.ts +1 -1
- package/appUtils/keyCodes/keys.ios.js +0 -46
- /package/appUtils/HooksManager/{logger.js → logger.ts} +0 -0
- /package/appUtils/{directionHelper.js → directionHelper.ts} +0 -0
- /package/appUtils/keyCodes/{androidTVKeys.js → androidTVKeys.ts} +0 -0
- /package/appUtils/keyCodes/{keys.web.js → keys/keys.web.ts} +0 -0
- /package/appUtils/{localizationsHelper.js → localizationsHelper.ts} +0 -0
- /package/domUtils/{logger.js → logger.ts} +0 -0
|
@@ -5,7 +5,11 @@ import { SEEK_TYPE } from "../const";
|
|
|
5
5
|
import { createLogger } from "../../../logger";
|
|
6
6
|
import { Player } from "../../../appUtils/playerManager/player";
|
|
7
7
|
import { SeekKeyHandlerListener } from "../../../appUtils/keyInputHandler/KeyInputHandler";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ISeekController,
|
|
10
|
+
ISeekControllerDelegate,
|
|
11
|
+
SeekIncrementalBaseStrategy,
|
|
12
|
+
} from "./ISeekController";
|
|
9
13
|
|
|
10
14
|
export const { log_warning, log_debug, log_info, log_error, log_verbose } =
|
|
11
15
|
createLogger({
|
|
@@ -23,17 +27,16 @@ const CONFIG_TAP_SEEK = {
|
|
|
23
27
|
};
|
|
24
28
|
|
|
25
29
|
const CONFIG_LONG_PRESS = {
|
|
26
|
-
TIMER_INTERVAL_MS:
|
|
27
|
-
SKIP_INCREMENT_STEP: 5,
|
|
28
|
-
MAX_SKIP_PER_TICK: 300,
|
|
29
|
-
INITIAL_SKIP_AMOUNT: 10,
|
|
30
|
+
TIMER_INTERVAL_MS: 200,
|
|
30
31
|
};
|
|
31
32
|
|
|
32
33
|
const LONG_PRESS_THRESHOLD = 500;
|
|
34
|
+
const SEEK_END_TIMEOUT_DURATION = 700;
|
|
35
|
+
// prettier-ignore
|
|
33
36
|
|
|
34
37
|
export class TVSeekController
|
|
35
38
|
implements SeekKeyHandlerListener, ISeekControllerDelegate {
|
|
36
|
-
public
|
|
39
|
+
public delayedSeekPosition: number | null = null;
|
|
37
40
|
private readonly playerController: Player;
|
|
38
41
|
private delayedSeekProgressSubject = new BehaviorSubject<number | null>(null);
|
|
39
42
|
isPlayerInitiallyPaused: null | boolean = null;
|
|
@@ -43,14 +46,20 @@ export class TVSeekController
|
|
|
43
46
|
private readonly tapSeekController: TapSeekController;
|
|
44
47
|
private readonly longPressSeekController: LongPressSeekController;
|
|
45
48
|
private longPressThresholdTimeout: any | null = null;
|
|
49
|
+
private seekEndTimeout: any | null = null;
|
|
46
50
|
|
|
47
51
|
constructor(playerController: Player) {
|
|
48
52
|
this.playerController = playerController;
|
|
49
53
|
|
|
50
|
-
this.tapSeekController = new TapSeekController(
|
|
54
|
+
this.tapSeekController = new TapSeekController(
|
|
55
|
+
this,
|
|
56
|
+
new SeekIncrementalBaseStrategy(),
|
|
57
|
+
CONFIG_TAP_SEEK
|
|
58
|
+
);
|
|
51
59
|
|
|
52
60
|
this.longPressSeekController = new LongPressSeekController(
|
|
53
61
|
this,
|
|
62
|
+
new SeekIncrementalBaseStrategy(),
|
|
54
63
|
CONFIG_LONG_PRESS
|
|
55
64
|
);
|
|
56
65
|
|
|
@@ -64,30 +73,28 @@ export class TVSeekController
|
|
|
64
73
|
setStrategy = (seekStrategy: SEEK_STRATEGY) => {
|
|
65
74
|
switch (seekStrategy) {
|
|
66
75
|
case SEEK_STRATEGY.TAP_SEEK:
|
|
67
|
-
clearTimeout(this.longPressThresholdTimeout);
|
|
68
|
-
this.longPressThresholdTimeout = null;
|
|
69
76
|
this.currentSeekController = this.tapSeekController;
|
|
77
|
+
log_debug("TVSeekController: setStrategy - TAP_SEEK");
|
|
70
78
|
|
|
71
79
|
break;
|
|
72
80
|
case SEEK_STRATEGY.AUTO_SEEK:
|
|
73
|
-
this.currentSeekController.reset();
|
|
74
81
|
this.currentSeekController = this.longPressSeekController;
|
|
82
|
+
log_debug("TVSeekController: setStrategy - AUTO_SEEK");
|
|
83
|
+
|
|
75
84
|
break;
|
|
76
85
|
default:
|
|
77
86
|
}
|
|
78
87
|
};
|
|
79
88
|
|
|
80
89
|
handleStartSeek = (seekType: SEEK_TYPE) => {
|
|
81
|
-
if (this.currentSeekType !== seekType) {
|
|
82
|
-
this.resetAll();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
90
|
this.currentSeekType = seekType;
|
|
86
91
|
|
|
87
92
|
if (this.isPlayerInitiallyPaused === null) {
|
|
88
93
|
this.isPlayerInitiallyPaused = this.playerController.isPaused();
|
|
89
94
|
}
|
|
90
95
|
|
|
96
|
+
this.clearLongPressThresholdTimeout();
|
|
97
|
+
this.clearSeekCompleteTimeout();
|
|
91
98
|
this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
|
|
92
99
|
this.currentSeekController.onStartSeek(seekType);
|
|
93
100
|
|
|
@@ -110,8 +117,8 @@ export class TVSeekController
|
|
|
110
117
|
};
|
|
111
118
|
|
|
112
119
|
onSeekEnd = () => {
|
|
120
|
+
this.clearLongPressThresholdTimeout();
|
|
113
121
|
this.currentSeekController.onSeekEnd();
|
|
114
|
-
this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
|
|
115
122
|
};
|
|
116
123
|
|
|
117
124
|
onRewindPressOut = () => {
|
|
@@ -122,40 +129,39 @@ export class TVSeekController
|
|
|
122
129
|
this.onSeekEnd();
|
|
123
130
|
};
|
|
124
131
|
|
|
125
|
-
|
|
126
|
-
if (this.
|
|
132
|
+
onVideoProgress = (position: number) => {
|
|
133
|
+
if (this.delayedSeekPosition !== null) {
|
|
127
134
|
return;
|
|
128
135
|
}
|
|
129
136
|
|
|
130
|
-
// TODO: If 1 second after seek, send
|
|
131
|
-
|
|
132
137
|
this.delayedSeekProgressSubject.next(position);
|
|
133
138
|
};
|
|
134
139
|
|
|
135
|
-
handleDelayedSeek = (offset: number) => {
|
|
140
|
+
handleDelayedSeek = (offset: number = 0) => {
|
|
136
141
|
this.handlePlayerPause();
|
|
137
142
|
|
|
138
|
-
const
|
|
139
|
-
|
|
143
|
+
const currentPos =
|
|
144
|
+
this.delayedSeekPosition === null
|
|
145
|
+
? this.playerController.getPosition()
|
|
146
|
+
: this.delayedSeekPosition;
|
|
147
|
+
|
|
140
148
|
let targetPos = currentPos;
|
|
141
149
|
|
|
142
150
|
if (this.currentSeekType === SEEK_TYPE.FORWARD) {
|
|
143
151
|
targetPos = Math.min(
|
|
144
|
-
currentPos +
|
|
152
|
+
currentPos + offset,
|
|
145
153
|
this.playerController.getSeekableDuration()
|
|
146
154
|
);
|
|
147
155
|
} else if (this.currentSeekType === SEEK_TYPE.REWIND) {
|
|
148
|
-
targetPos = Math.max(0, currentPos -
|
|
156
|
+
targetPos = Math.max(0, currentPos - offset);
|
|
149
157
|
} else {
|
|
150
158
|
log_warning(
|
|
151
159
|
`TVSeekController: handleDelayedSeek - invalid seek type: ${this.currentSeekType}`
|
|
152
160
|
);
|
|
153
161
|
}
|
|
154
162
|
|
|
155
|
-
this.delayedSeekOffset = newOffset;
|
|
156
|
-
|
|
157
163
|
log_debug(
|
|
158
|
-
`TVSeekController: handleDelayedSeek - targetPos: ${targetPos},
|
|
164
|
+
`TVSeekController: handleDelayedSeek - targetPos: ${targetPos}, skipTime: ${offset}`
|
|
159
165
|
);
|
|
160
166
|
|
|
161
167
|
const prevValue = this.delayedSeekProgressSubject.getValue();
|
|
@@ -168,9 +174,18 @@ export class TVSeekController
|
|
|
168
174
|
}
|
|
169
175
|
}
|
|
170
176
|
|
|
177
|
+
this.delayedSeekPosition = targetPos;
|
|
171
178
|
this.delayedSeekProgressSubject.next(targetPos);
|
|
172
179
|
};
|
|
173
180
|
|
|
181
|
+
handleSeekTo = (newPosition: number) => {
|
|
182
|
+
this.playerController.seekTo(newPosition);
|
|
183
|
+
|
|
184
|
+
if (!this.isPlayerInitiallyPaused) {
|
|
185
|
+
this.playerController.play();
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
174
189
|
handleSeek = (offset: number) => {
|
|
175
190
|
this.playerController[this.currentSeekType](offset);
|
|
176
191
|
|
|
@@ -180,11 +195,23 @@ export class TVSeekController
|
|
|
180
195
|
};
|
|
181
196
|
|
|
182
197
|
handleSeekComplete = () => {
|
|
183
|
-
this.
|
|
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);
|
|
184
211
|
};
|
|
185
212
|
|
|
186
|
-
|
|
187
|
-
return this.
|
|
213
|
+
isSeeking = (): boolean => {
|
|
214
|
+
return this.delayedSeekPosition !== null;
|
|
188
215
|
};
|
|
189
216
|
|
|
190
217
|
handlePlayerPause = () => {
|
|
@@ -195,12 +222,34 @@ export class TVSeekController
|
|
|
195
222
|
this.playerController.pause();
|
|
196
223
|
};
|
|
197
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
|
+
|
|
198
243
|
resetAll() {
|
|
199
244
|
log_debug("TVSeekController: Reset all states");
|
|
200
245
|
this.currentSeekType = null;
|
|
201
|
-
|
|
246
|
+
|
|
247
|
+
this.delayedSeekPosition = null;
|
|
202
248
|
this.isPlayerInitiallyPaused = null;
|
|
203
249
|
|
|
250
|
+
this.clearSeekCompleteTimeout();
|
|
251
|
+
this.clearLongPressThresholdTimeout();
|
|
252
|
+
|
|
204
253
|
this.tapSeekController.reset();
|
|
205
254
|
this.longPressSeekController.reset();
|
|
206
255
|
|
|
@@ -1,75 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
ISeekController,
|
|
3
|
+
ISeekControllerDelegate,
|
|
4
|
+
SeekIncrementalBaseStrategy,
|
|
5
|
+
} from "./ISeekController";
|
|
6
|
+
import { SEEK_TYPE } from "../const";
|
|
3
7
|
import { log_debug } from "./TVSeekController";
|
|
4
8
|
|
|
5
9
|
interface TapPressConfig {
|
|
6
10
|
CLICKS_BEFORE_PAUSE: number;
|
|
7
11
|
}
|
|
8
12
|
|
|
9
|
-
const getSkipTime = (multiplier: number) =>
|
|
10
|
-
Math.min(MAX_SEEK_TIME, SKIP_TIME_BASE * multiplier);
|
|
11
|
-
|
|
12
13
|
export class TapSeekController implements ISeekController {
|
|
13
|
-
|
|
14
|
-
private seekMultiplier = 1;
|
|
15
|
-
private readonly ON_PRESS_RESET_DURATION = 500; // ms
|
|
16
|
-
|
|
14
|
+
readonly title = "TapSeek";
|
|
17
15
|
constructor(
|
|
18
16
|
private seekControllerDelegate: ISeekControllerDelegate,
|
|
17
|
+
private seekIncrementalStrategy: SeekIncrementalBaseStrategy,
|
|
19
18
|
private config: TapPressConfig
|
|
20
19
|
) {}
|
|
21
20
|
|
|
22
21
|
onStartSeek = (seekType: SEEK_TYPE) => {
|
|
23
|
-
log_debug(
|
|
22
|
+
log_debug(`${this.title}: start tap seek type: ${seekType}.`);
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.tapSequenceTimeout = null;
|
|
28
|
-
}
|
|
24
|
+
const skipTime = this.seekIncrementalStrategy.getSkipTime();
|
|
25
|
+
const seekMultiplier = this.seekIncrementalStrategy.getSkipMultiplier();
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (this.seekMultiplier > this.config.CLICKS_BEFORE_PAUSE) {
|
|
27
|
+
if (seekMultiplier > this.config.CLICKS_BEFORE_PAUSE) {
|
|
33
28
|
log_debug(
|
|
34
|
-
|
|
29
|
+
`${this.title}: handle delayed seek type:${seekType} - skipTime: ${skipTime}, seekMultiplier: ${seekMultiplier}.`
|
|
35
30
|
);
|
|
36
31
|
|
|
37
32
|
this.seekControllerDelegate.handleDelayedSeek(skipTime);
|
|
38
33
|
} else {
|
|
39
34
|
log_debug(
|
|
40
|
-
|
|
35
|
+
`${this.title}: handle seek type:${seekType} - skipTime: ${skipTime}.`
|
|
41
36
|
);
|
|
42
37
|
|
|
43
38
|
this.seekControllerDelegate.handleSeek(skipTime);
|
|
44
39
|
}
|
|
45
40
|
|
|
46
|
-
this.
|
|
41
|
+
this.seekIncrementalStrategy.increment();
|
|
47
42
|
};
|
|
48
43
|
|
|
49
44
|
onSeekEnd = () => {
|
|
50
|
-
this.
|
|
51
|
-
if (this.seekControllerDelegate.delayedSeekOffset !== null) {
|
|
52
|
-
this.seekControllerDelegate.handleSeek(
|
|
53
|
-
this.seekControllerDelegate.delayedSeekOffset
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
log_debug(
|
|
58
|
-
`TapSeekController: Tap sequence timeout fired, delayedSeekOffset: ${this.seekControllerDelegate.delayedSeekOffset}.`
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
this.seekControllerDelegate.handleSeekComplete();
|
|
62
|
-
}, this.ON_PRESS_RESET_DURATION);
|
|
45
|
+
this.seekControllerDelegate.handleSeekComplete();
|
|
63
46
|
};
|
|
64
47
|
|
|
65
48
|
reset = () => {
|
|
66
|
-
log_debug("
|
|
49
|
+
log_debug("{this.title}: Reset states");
|
|
67
50
|
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
if (this.tapSequenceTimeout) {
|
|
71
|
-
clearTimeout(this.tapSequenceTimeout);
|
|
72
|
-
this.tapSequenceTimeout = null;
|
|
73
|
-
}
|
|
51
|
+
this.seekIncrementalStrategy.reset();
|
|
74
52
|
};
|
|
75
53
|
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { act, renderHook } from "@testing-library/react-hooks";
|
|
2
|
+
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
|
|
3
|
+
|
|
4
|
+
import { ON_HOLD_INTERVAL, SEEK_TYPE, SKIP_TIME_BASE } from "../const";
|
|
5
|
+
|
|
6
|
+
import { useAutoSeek } from "../useAutoSeek";
|
|
7
|
+
|
|
8
|
+
jest.useFakeTimers({ legacyFakeTimers: true });
|
|
9
|
+
|
|
10
|
+
const rewind = jest.fn();
|
|
11
|
+
const forward = jest.fn();
|
|
12
|
+
|
|
13
|
+
jest
|
|
14
|
+
.spyOn(playerManager, "getInstanceController")
|
|
15
|
+
.mockReturnValue({ rewind, forward });
|
|
16
|
+
|
|
17
|
+
describe("useAutoSeek", () => {
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
rewind.mockReset();
|
|
20
|
+
forward.mockReset();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("autoSeekStart", () => {
|
|
24
|
+
it("should call forward method on playerInstance", () => {
|
|
25
|
+
const { result } = renderHook(() => useAutoSeek());
|
|
26
|
+
|
|
27
|
+
act(() => {
|
|
28
|
+
result.current.autoSeekStart(SEEK_TYPE.FORWARD);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
expect(forward).toBeCalled();
|
|
32
|
+
result.current.autoSeekStop();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should call rewind method on playerManager", () => {
|
|
36
|
+
const { result } = renderHook(() => useAutoSeek());
|
|
37
|
+
|
|
38
|
+
act(() => {
|
|
39
|
+
result.current.autoSeekStart(SEEK_TYPE.REWIND);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
expect(rewind).toBeCalled();
|
|
43
|
+
result.current.autoSeekStop();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("should call rewind with default skip time", () => {
|
|
47
|
+
const { result } = renderHook(() => useAutoSeek());
|
|
48
|
+
|
|
49
|
+
act(() => {
|
|
50
|
+
result.current.autoSeekStart(SEEK_TYPE.REWIND);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
expect(rewind).toBeCalledWith(SKIP_TIME_BASE);
|
|
54
|
+
result.current.autoSeekStop();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("should call forward with default skip time", () => {
|
|
58
|
+
const { result } = renderHook(() => useAutoSeek());
|
|
59
|
+
|
|
60
|
+
act(() => {
|
|
61
|
+
result.current.autoSeekStart(SEEK_TYPE.FORWARD);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
expect(forward).toBeCalledWith(SKIP_TIME_BASE);
|
|
65
|
+
result.current.autoSeekStop();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should call rewind in intervals set in configuration", () => {
|
|
69
|
+
const { result } = renderHook(() => useAutoSeek());
|
|
70
|
+
|
|
71
|
+
act(() => {
|
|
72
|
+
result.current.autoSeekStart(SEEK_TYPE.REWIND);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
expect(rewind).toBeCalled();
|
|
76
|
+
jest.advanceTimersByTime(ON_HOLD_INTERVAL * 3);
|
|
77
|
+
expect(rewind).toBeCalledTimes(4);
|
|
78
|
+
result.current.autoSeekStop();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("should call forward in intervals set in configuration", () => {
|
|
82
|
+
const { result } = renderHook(() => useAutoSeek());
|
|
83
|
+
|
|
84
|
+
act(() => {
|
|
85
|
+
result.current.autoSeekStart(SEEK_TYPE.FORWARD);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
expect(forward).toBeCalled();
|
|
89
|
+
jest.advanceTimersByTime(ON_HOLD_INTERVAL * 3);
|
|
90
|
+
expect(forward).toBeCalledTimes(4);
|
|
91
|
+
result.current.autoSeekStop();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("autoSeekStop", () => {
|
|
96
|
+
it("should stop calling playerManager method after autoSeekStop is called", () => {
|
|
97
|
+
const { result } = renderHook(() => useAutoSeek());
|
|
98
|
+
|
|
99
|
+
act(() => {
|
|
100
|
+
result.current.autoSeekStart(SEEK_TYPE.FORWARD);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
expect(forward).toBeCalled();
|
|
104
|
+
jest.advanceTimersByTime(ON_HOLD_INTERVAL * 3);
|
|
105
|
+
expect(forward).toBeCalledTimes(4);
|
|
106
|
+
|
|
107
|
+
act(() => {
|
|
108
|
+
result.current.autoSeekStop();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
jest.advanceTimersByTime(ON_HOLD_INTERVAL * 3);
|
|
112
|
+
expect(forward).toBeCalledTimes(4);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { renderHook } from "@testing-library/react-hooks";
|
|
2
|
+
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
|
|
3
|
+
import { useTapSeek } from "../useTapSeek";
|
|
4
|
+
|
|
5
|
+
import { ON_PRESS_RESET_DURATION, SEEK_TYPE, SKIP_TIME_BASE } from "../const";
|
|
6
|
+
|
|
7
|
+
const rewind = jest.fn();
|
|
8
|
+
const forward = jest.fn();
|
|
9
|
+
|
|
10
|
+
jest
|
|
11
|
+
.spyOn(playerManager, "getInstanceController")
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
.mockImplementation(() => ({ rewind, forward }));
|
|
14
|
+
|
|
15
|
+
describe("useTapSeek", () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
rewind.mockReset();
|
|
18
|
+
forward.mockReset();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe("forward", () => {
|
|
22
|
+
it("should call forward method on playerManager", () => {
|
|
23
|
+
const { result } = renderHook(() => useTapSeek());
|
|
24
|
+
|
|
25
|
+
result.current(SEEK_TYPE.FORWARD);
|
|
26
|
+
expect(forward).toBeCalled();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should call forward with default skip time", () => {
|
|
30
|
+
const { result } = renderHook(() => useTapSeek());
|
|
31
|
+
|
|
32
|
+
result.current(SEEK_TYPE.FORWARD);
|
|
33
|
+
expect(forward).toBeCalledWith(SKIP_TIME_BASE);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should multiply skip time for every call", async () => {
|
|
37
|
+
const { result } = renderHook(() => useTapSeek());
|
|
38
|
+
|
|
39
|
+
result.current(SEEK_TYPE.FORWARD);
|
|
40
|
+
expect(forward).toBeCalledWith(SKIP_TIME_BASE);
|
|
41
|
+
result.current(SEEK_TYPE.FORWARD);
|
|
42
|
+
expect(forward).toBeCalledWith(SKIP_TIME_BASE * 2);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should reset multiplier if waiting more then resetDuration between press actions", () => {
|
|
46
|
+
const { result, waitFor } = renderHook(() => useTapSeek());
|
|
47
|
+
|
|
48
|
+
result.current(SEEK_TYPE.FORWARD);
|
|
49
|
+
expect(forward).toBeCalledWith(SKIP_TIME_BASE);
|
|
50
|
+
waitFor(jest.fn(), { timeout: ON_PRESS_RESET_DURATION });
|
|
51
|
+
result.current(SEEK_TYPE.FORWARD);
|
|
52
|
+
expect(forward).toBeCalledWith(SKIP_TIME_BASE);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("rewind", () => {
|
|
57
|
+
it("should call rewind method on playerManager", () => {
|
|
58
|
+
const { result } = renderHook(() => useTapSeek());
|
|
59
|
+
|
|
60
|
+
result.current(SEEK_TYPE.REWIND);
|
|
61
|
+
expect(rewind).toBeCalled();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should call rewind with default skip time", () => {
|
|
65
|
+
const { result } = renderHook(() => useTapSeek());
|
|
66
|
+
|
|
67
|
+
result.current(SEEK_TYPE.REWIND);
|
|
68
|
+
expect(rewind).toBeCalledWith(SKIP_TIME_BASE);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("should multiply skip time for every call", async () => {
|
|
72
|
+
const { result } = renderHook(() => useTapSeek());
|
|
73
|
+
|
|
74
|
+
result.current(SEEK_TYPE.REWIND);
|
|
75
|
+
expect(rewind).toBeCalledWith(SKIP_TIME_BASE);
|
|
76
|
+
result.current(SEEK_TYPE.REWIND);
|
|
77
|
+
expect(rewind).toBeCalledWith(SKIP_TIME_BASE * 2);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("mixed usage", () => {
|
|
82
|
+
it("should reset timer if different type of event is emitted", () => {
|
|
83
|
+
const { result } = renderHook(() => useTapSeek());
|
|
84
|
+
result.current(SEEK_TYPE.REWIND);
|
|
85
|
+
expect(rewind).toBeCalledWith(SKIP_TIME_BASE);
|
|
86
|
+
|
|
87
|
+
result.current(SEEK_TYPE.REWIND);
|
|
88
|
+
expect(rewind).toBeCalledWith(SKIP_TIME_BASE * 2);
|
|
89
|
+
|
|
90
|
+
result.current(SEEK_TYPE.FORWARD);
|
|
91
|
+
expect(forward).toBeCalledWith(SKIP_TIME_BASE);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -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
|
-
|
|
12
|
-
attachLifeCycleMethods,
|
|
13
|
-
createReactRef,
|
|
14
|
-
mergeChildrenProps,
|
|
15
|
-
} = require("../index");
|
|
16
|
-
|
|
17
|
-
const createRef = require("create-react-ref/lib/createRef");
|
|
10
|
+
import { attachLifeCycleMethods, createReactRef, mergeChildrenProps } from "..";
|
|
18
11
|
|
|
19
12
|
describe("attachLifeCycleMethods", () => {
|
|
20
13
|
let addLifeCycleMethodsSpy;
|
|
@@ -50,30 +43,19 @@ describe("attachLifeCycleMethods", () => {
|
|
|
50
43
|
|
|
51
44
|
describe("createReactRef", () => {
|
|
52
45
|
it("calls the React.createRef function if it exists", () => {
|
|
53
|
-
jest.
|
|
54
|
-
|
|
55
|
-
jest.doMock("react", () => ({
|
|
56
|
-
...jest.requireActual("react"),
|
|
57
|
-
createRef: jest.fn(),
|
|
58
|
-
}));
|
|
59
|
-
|
|
60
|
-
const React = require("react");
|
|
46
|
+
jest.clearAllMocks();
|
|
61
47
|
|
|
62
|
-
createReactRef();
|
|
63
|
-
expect(
|
|
64
|
-
expect(createRef).not.toHaveBeenCalled();
|
|
48
|
+
const ref = createReactRef();
|
|
49
|
+
expect(ref).toHaveProperty("current");
|
|
65
50
|
});
|
|
66
51
|
|
|
67
52
|
it("calls the polyfill if React.createRef doesn't exist", () => {
|
|
68
|
-
jest.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
createReactRef();
|
|
76
|
-
expect(createRef).toHaveBeenCalled();
|
|
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;
|
|
77
59
|
});
|
|
78
60
|
});
|
|
79
61
|
|