@applicaster/zapp-react-native-utils 12.0.0-alpha.4043183114 → 12.0.0-alpha.4155487673
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/analyticsUtils/AnalyticPlayerListener.ts +141 -0
- package/analyticsUtils/PlayerAnalyticsManager.ts +90 -0
- package/analyticsUtils/{analyticsTracker.ts → playerAnalyticsTracker.ts} +19 -10
- package/appUtils/HooksManager/{Hook.ts → Hook.js} +11 -17
- package/appUtils/HooksManager/{constants.ts → constants.js} +1 -1
- package/appUtils/HooksManager/{index.ts → index.js} +109 -98
- package/appUtils/RiverFocusManager/index.js +12 -17
- package/appUtils/accessibilityManager/hooks.ts +16 -7
- package/appUtils/accessibilityManager/index.ts +42 -26
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +3 -2
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +3 -1
- package/appUtils/{index.ts → index.js} +1 -1
- package/appUtils/keyCodes/{index.ts → index.js} +0 -2
- package/appUtils/keyCodes/{keys/keyEventMapper.ts → keys.android.js} +19 -0
- package/appUtils/keyCodes/keys.ios.js +46 -0
- package/appUtils/platform/platformUtils.ts +14 -0
- package/appUtils/playerManager/index.ts +9 -27
- package/appUtils/playerManager/playerNative.ts +1 -1
- package/cellUtils/index.ts +38 -5
- package/domUtils/{cookieManager.ts → cookieManager.js} +2 -1
- package/functionUtils/index.ts +11 -15
- package/index.d.ts +15 -0
- package/modalState/index.ts +5 -1
- package/navigationUtils/index.ts +5 -14
- package/numberUtils/__tests__/toNumber.test.ts +2 -2
- package/package.json +2 -2
- package/playerUtils/imaScriptDom.ts +59 -0
- package/reactHooks/debugging/__tests__/index.test.js +81 -11
- package/reactHooks/navigation/index.ts +4 -7
- package/reactHooks/resolvers/useCellResolver.ts +5 -1
- package/reactUtils/index.ts +15 -2
- package/appUtils/HooksManager/types.ts +0 -93
- package/appUtils/keyCodes/keys/index.ts +0 -3
- package/appUtils/keyCodes/keys/keys.android.ts +0 -18
- package/appUtils/keyCodes/keys/keys.ios.ts +0 -25
- package/appUtils/keyCodes/keys/keys.ts +0 -15
- /package/appUtils/HooksManager/{logger.ts → logger.js} +0 -0
- /package/appUtils/{directionHelper.ts → directionHelper.js} +0 -0
- /package/appUtils/keyCodes/{androidTVKeys.ts → androidTVKeys.js} +0 -0
- /package/appUtils/keyCodes/{keys/keys.web.ts → keys.web.js} +0 -0
- /package/appUtils/keyCodes/{keys/keysByPlatform.ts → keysByPlatform.js} +0 -0
- /package/appUtils/{localizationsHelper.ts → localizationsHelper.js} +0 -0
- /package/domUtils/{logger.ts → logger.js} +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { PlayerAnalyticsTracker } from "./playerAnalyticsTracker";
|
|
2
|
+
import { Player } from "../appUtils/playerManager/player";
|
|
3
|
+
import { AD_EVENT, GENERAL_EVENT, PLAYBACK_EVENT, QOS_EVENT } from "./events";
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
analyticsTracker: any;
|
|
7
|
+
player: any;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/* eslint brace-style: 0 */ // --> OFF
|
|
11
|
+
export class AnalyticPlayerListener
|
|
12
|
+
implements QuickBrickPlayer.SharedPlayerCallBacks
|
|
13
|
+
{
|
|
14
|
+
static analyticsListenerID = "analytics-listener";
|
|
15
|
+
private analyticsTracker: PlayerAnalyticsTracker;
|
|
16
|
+
private player: Player;
|
|
17
|
+
|
|
18
|
+
private onVideoLoadCalled; // android only
|
|
19
|
+
|
|
20
|
+
constructor(props: Props) {
|
|
21
|
+
this.analyticsTracker = props.analyticsTracker;
|
|
22
|
+
this.player = props.player;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
handleAnalyticEvent = (event, data = {}) => {
|
|
26
|
+
if (this.analyticsTracker?.handleAnalyticEvent) {
|
|
27
|
+
this.analyticsTracker?.handleAnalyticEvent?.(event, {
|
|
28
|
+
...data,
|
|
29
|
+
player_type: this.player.playerPluginId,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
onVideoEnd = () => {
|
|
35
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.complete);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
onError = (err: Error) => {
|
|
39
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.error, err); // TODO: Check error format
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
onPlayerPause = (event) => {
|
|
43
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.pause, event);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
onPlayerResume = (event) => {
|
|
47
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.play, event);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
onPlayerSeekComplete = (event) => {
|
|
51
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.seek_complete, event);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
onPlayerSeekStart = (event) => {
|
|
55
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.seek_start, event);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
onBufferStart = (event) => {
|
|
59
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.buffer_start, event);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
onBufferComplete = (event) => {
|
|
63
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.buffer_complete, event);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Not implemented
|
|
67
|
+
onPlayerStop = (event) => {
|
|
68
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.stop, event);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// TODO: Implement method on native
|
|
72
|
+
onVideoBandwidthUpdate = (event) => {
|
|
73
|
+
this.handleAnalyticEvent(QOS_EVENT.bitrate_changed, event);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
onAdBegin = (event) => {
|
|
77
|
+
this.handleAnalyticEvent(AD_EVENT.ad_start, event);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
onAdBreakBegin = (event) => {
|
|
81
|
+
this.handleAnalyticEvent(AD_EVENT.ad_break_start, event);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
onAdBreakEnd = (event) => {
|
|
85
|
+
this.handleAnalyticEvent(AD_EVENT.ad_break_completed, event);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
onAdEnd = (event) => {
|
|
89
|
+
this.handleAnalyticEvent(AD_EVENT.ad_complete, event);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
onAdError = (event) => {
|
|
93
|
+
this.handleAnalyticEvent(AD_EVENT.ad_error, event);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
onAdRequest = (event) => {
|
|
97
|
+
this.handleAnalyticEvent(AD_EVENT.ad_request, event);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
onAdClicked = (event) => {
|
|
101
|
+
this.handleAnalyticEvent(AD_EVENT.ad_clicked, event);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
onAdTapped = (event) => {
|
|
105
|
+
this.handleAnalyticEvent(AD_EVENT.ad_tapped, event);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
onVideoLoad = () => {
|
|
109
|
+
// if (!this.state.isAd && !this.onVideoLoadCalled) {
|
|
110
|
+
if (!this.player.isAd() && !this.onVideoLoadCalled) {
|
|
111
|
+
this.onVideoLoadCalled = true;
|
|
112
|
+
|
|
113
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.load_video, {
|
|
114
|
+
player_type: this.player.playerPluginId,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
onPlayerSessionEnd = () => {
|
|
120
|
+
// TODO: Implement method on native android, ios exists
|
|
121
|
+
this.handleAnalyticEvent(GENERAL_EVENT.session_end);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
onPlayerSessionStart = () => {
|
|
125
|
+
// TODO: Implement method on native android, ios exists
|
|
126
|
+
|
|
127
|
+
this.handleAnalyticEvent(GENERAL_EVENT.session_start);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
onPlayerNext = ({ nativeEvent }) => {
|
|
131
|
+
// TODO: Implement method on native
|
|
132
|
+
|
|
133
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.next, nativeEvent);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
onPlayerPrevious = ({ nativeEvent }) => {
|
|
137
|
+
// TODO: Implement method on native
|
|
138
|
+
|
|
139
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.previous, nativeEvent);
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PlayerAnalyticsTracker,
|
|
3
|
+
PlayerAnalyticsTrackerI,
|
|
4
|
+
} from "./playerAnalyticsTracker";
|
|
5
|
+
import {
|
|
6
|
+
PlayerLifecycleListener,
|
|
7
|
+
PlayerManager,
|
|
8
|
+
} from "../appUtils/playerManager";
|
|
9
|
+
import { Player } from "../appUtils/playerManager/player";
|
|
10
|
+
import { AnalyticPlayerListener } from "./AnalyticPlayerListener";
|
|
11
|
+
import { PlayerRole } from "../appUtils/playerManager/conts";
|
|
12
|
+
|
|
13
|
+
enum PlayerAnalyticsTrackerType {
|
|
14
|
+
PlayerAnalyticsTracker = "PlayerAnalyticsTracker",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class PlayerAnalyticsTrackerFactory {
|
|
18
|
+
createTracker(type: PlayerAnalyticsTrackerType) {
|
|
19
|
+
switch (type) {
|
|
20
|
+
case PlayerAnalyticsTrackerType.PlayerAnalyticsTracker:
|
|
21
|
+
return new PlayerAnalyticsTracker();
|
|
22
|
+
default:
|
|
23
|
+
return new PlayerAnalyticsTracker();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class PlayerAnalyticsManager implements PlayerLifecycleListener {
|
|
29
|
+
static instance: PlayerAnalyticsManager;
|
|
30
|
+
private trackers: Record<string, PlayerAnalyticsTrackerI> = {};
|
|
31
|
+
private trackerFactory: PlayerAnalyticsTrackerFactory;
|
|
32
|
+
|
|
33
|
+
public getTracker(
|
|
34
|
+
id: string,
|
|
35
|
+
type: PlayerAnalyticsTrackerType = PlayerAnalyticsTrackerType.PlayerAnalyticsTracker
|
|
36
|
+
): PlayerAnalyticsTrackerI {
|
|
37
|
+
if (!this.trackers[id]) {
|
|
38
|
+
this.trackers[id] = this.trackerFactory.createTracker(type);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return this.trackers[id];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
constructor(trackerFactory: PlayerAnalyticsTrackerFactory) {
|
|
45
|
+
this.trackerFactory = trackerFactory;
|
|
46
|
+
this.startListenPlayerManager();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static getInstance(
|
|
50
|
+
trackerFactory: PlayerAnalyticsTrackerFactory = new PlayerAnalyticsTrackerFactory()
|
|
51
|
+
): PlayerAnalyticsManager {
|
|
52
|
+
if (!PlayerAnalyticsManager.instance) {
|
|
53
|
+
PlayerAnalyticsManager.instance = new PlayerAnalyticsManager(
|
|
54
|
+
trackerFactory
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return PlayerAnalyticsManager.instance;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private startListenPlayerManager() {
|
|
62
|
+
PlayerManager.getInstance().addLifecycleListener(this);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// PlayerLifecycleListener
|
|
66
|
+
|
|
67
|
+
onRegistered = (player: Player) => {
|
|
68
|
+
if (player.playerRole !== PlayerRole.Primary) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const tracker = this.getTracker(player.playerId);
|
|
73
|
+
tracker.setPlayer(player);
|
|
74
|
+
|
|
75
|
+
const analyticsListener = new AnalyticPlayerListener({
|
|
76
|
+
analyticsTracker: tracker,
|
|
77
|
+
player,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
player.addListener({
|
|
81
|
+
id: AnalyticPlayerListener.analyticsListenerID,
|
|
82
|
+
listener: analyticsListener,
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
onUnRegistered = (player: Player) => {
|
|
87
|
+
player.removeListener(AnalyticPlayerListener.analyticsListenerID);
|
|
88
|
+
delete this.trackers[player.playerId];
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -5,16 +5,25 @@ import { postAnalyticEvent } from "./manager";
|
|
|
5
5
|
import { isLive } from "../playerUtils";
|
|
6
6
|
import { extensionsEvents } from "./AnalyticsEvents/helper";
|
|
7
7
|
import { AD_EVENT, EVENT_TYPES, PLAYER_DISPLAY_STATES } from "./events";
|
|
8
|
+
import { Player } from "../appUtils/playerManager/player";
|
|
8
9
|
|
|
9
|
-
export
|
|
10
|
+
export interface PlayerAnalyticsTrackerI {
|
|
11
|
+
handleAnalyticEvent(
|
|
12
|
+
event: QuickBrickPlayer.Events,
|
|
13
|
+
eventData?: QuickBrickPlayer.EventData
|
|
14
|
+
): void;
|
|
15
|
+
setPlayer(player: Player): void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class PlayerAnalyticsTracker implements PlayerAnalyticsTrackerI {
|
|
10
19
|
adTime: number | string;
|
|
11
20
|
mediaTime: number | string;
|
|
12
|
-
entry: ZappEntry;
|
|
13
21
|
eventType: string;
|
|
14
22
|
playerState: QuickBrickPlayer.NativePlayerState;
|
|
23
|
+
private player: Player;
|
|
15
24
|
|
|
16
|
-
|
|
17
|
-
this.
|
|
25
|
+
setPlayer(player: Player) {
|
|
26
|
+
this.player = player;
|
|
18
27
|
}
|
|
19
28
|
|
|
20
29
|
isAdBreak(event: string): boolean {
|
|
@@ -30,6 +39,10 @@ export class AnalyticsTracker {
|
|
|
30
39
|
return !!isAdBreak;
|
|
31
40
|
}
|
|
32
41
|
|
|
42
|
+
get entry(): ZappEntry {
|
|
43
|
+
return this.player?.getEntry();
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
getDuration(
|
|
34
47
|
event: QuickBrickPlayer.Events,
|
|
35
48
|
eventData: QuickBrickPlayer.EventData
|
|
@@ -215,13 +228,9 @@ export class AnalyticsTracker {
|
|
|
215
228
|
|
|
216
229
|
handleAnalyticEvent(
|
|
217
230
|
event: QuickBrickPlayer.Events,
|
|
218
|
-
eventData: QuickBrickPlayer.EventData = {}
|
|
219
|
-
entry: ZappEntry,
|
|
220
|
-
playerState = null
|
|
231
|
+
eventData: QuickBrickPlayer.EventData = {}
|
|
221
232
|
) {
|
|
222
|
-
this.
|
|
223
|
-
this.playerState = playerState;
|
|
224
|
-
|
|
233
|
+
this.playerState = this.player?.getState();
|
|
225
234
|
postAnalyticEvent(event, this.prepareAnalyticPayload(event, eventData));
|
|
226
235
|
}
|
|
227
236
|
}
|
|
@@ -4,7 +4,6 @@ import { isFunction } from "../../functionUtils";
|
|
|
4
4
|
import { HOOKS_EVENTS, HOOKS_TRANSITION_TYPE } from "./constants";
|
|
5
5
|
|
|
6
6
|
import { hooksManagerLogger } from "./logger";
|
|
7
|
-
import type { Hook as HookInterface, HookIniObj } from "./types";
|
|
8
7
|
|
|
9
8
|
const BASE_HOOK_PROPERTIES = ["screen_id", "identifier", "weight"];
|
|
10
9
|
|
|
@@ -15,9 +14,7 @@ const BASE_HOOK_PROPERTIES = ["screen_id", "identifier", "weight"];
|
|
|
15
14
|
* @param {string} hookEventName
|
|
16
15
|
* @returns {number} index
|
|
17
16
|
*/
|
|
18
|
-
const hookState
|
|
19
|
-
arg0: typeof HOOKS_EVENTS[keyof typeof HOOKS_EVENTS]
|
|
20
|
-
) => number = R.indexOf(R.__, R.values(HOOKS_EVENTS));
|
|
17
|
+
const hookState = R.indexOf(R.__, R.values(HOOKS_EVENTS));
|
|
21
18
|
|
|
22
19
|
/**
|
|
23
20
|
* assigns property to a given context
|
|
@@ -31,20 +28,17 @@ function assignProp(context) {
|
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
/**
|
|
34
|
-
* Representation of a hook plugin
|
|
31
|
+
* Representation of a hook plugin with full data
|
|
35
32
|
*/
|
|
36
|
-
export class Hook
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
public configuration;
|
|
46
|
-
|
|
47
|
-
constructor({ hook, hooks, manager }: HookIniObj) {
|
|
33
|
+
export class Hook {
|
|
34
|
+
/**
|
|
35
|
+
* constructs the hook
|
|
36
|
+
* @param {object} Options
|
|
37
|
+
* @param {object} Options.hook hook object
|
|
38
|
+
* @param {Array<Object>} Options.hooks array of hooks siblings in the current process
|
|
39
|
+
* @param {object} manager hook manager to process the hooks
|
|
40
|
+
*/
|
|
41
|
+
constructor({ hook, hooks, manager }) {
|
|
48
42
|
R.forEachObjIndexed(assignProp(this), hook);
|
|
49
43
|
this.manager = manager;
|
|
50
44
|
|
|
@@ -10,68 +10,14 @@ import { Hook } from "./Hook";
|
|
|
10
10
|
import { HOOKS_EVENTS, HOOKS_TYPE } from "./constants";
|
|
11
11
|
|
|
12
12
|
import { hooksManagerLogger } from "./logger";
|
|
13
|
-
import { HookManager, HookManagerArgs } from "./types";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* orders the hooks according to their weight
|
|
17
|
-
* @param {Array<object>} hooks to sort out
|
|
18
|
-
* @returns {Array<object>} sorted hooks
|
|
19
|
-
*/
|
|
20
|
-
function orderHooksByWeight(hooks) {
|
|
21
|
-
return R.sortBy(R.compose(Number, R.prop("weight")), hooks);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function executeOnNextHook(hooks, payload, callback) {
|
|
25
|
-
const [nextHook, ...restOfHooks] = orderHooksByWeight(hooks);
|
|
26
|
-
|
|
27
|
-
if (nextHook) {
|
|
28
|
-
nextHook.execute(payload, callback(nextHook, restOfHooks, payload));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* tells wether the current river is related to a player plugin, or the default player
|
|
34
|
-
* @param {Object} river
|
|
35
|
-
* @returns {boolean}
|
|
36
|
-
*/
|
|
37
|
-
function riverIsPlayer(river, plugins) {
|
|
38
|
-
const { screenType, plugin_type } = river;
|
|
39
|
-
|
|
40
|
-
if (screenType || plugin_type) {
|
|
41
|
-
return screenType === "playable" || plugin_type === "player";
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const { type } = river;
|
|
45
|
-
|
|
46
|
-
return R.compose(
|
|
47
|
-
R.propEq("type", "player"),
|
|
48
|
-
R.defaultTo({}),
|
|
49
|
-
R.find(R.propEq("identifier", type))
|
|
50
|
-
)(plugins);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Injects the hooks for the player
|
|
55
|
-
* @param _hookType type of hook
|
|
56
|
-
* @param plugins plugins
|
|
57
|
-
* @returns {Array<Object>}
|
|
58
|
-
*/
|
|
59
|
-
function injectPlayerHooks(_hookType: string, plugins): Hook[] {
|
|
60
|
-
const playerhooks: Hook[] = R.compose(
|
|
61
|
-
R.sortBy(R.prop("weight")),
|
|
62
|
-
R.map((plugin) => ({
|
|
63
|
-
identifier: plugin.identifier,
|
|
64
|
-
weight: R.path(["module", "weight"], plugin) || 1,
|
|
65
|
-
})),
|
|
66
|
-
R.filter(R.pathEq(["module", "hasPlayerHook"], true))
|
|
67
|
-
)(plugins);
|
|
68
|
-
|
|
69
|
-
return playerhooks;
|
|
70
|
-
}
|
|
71
13
|
|
|
72
14
|
/**
|
|
73
15
|
* creates a hooksManager object to handle the hooks process.
|
|
74
16
|
* it is based on the `subscriber` object
|
|
17
|
+
* @param {object} options
|
|
18
|
+
* @param {object} rivers map of rivers in the app
|
|
19
|
+
* @param {object} targetScreen rivers which we are navigating to
|
|
20
|
+
* @param {Array<object>} plugins array of plugins in the app
|
|
75
21
|
* @returns {object} hooksManager object - see Navigator for usage
|
|
76
22
|
*/
|
|
77
23
|
export function HooksManager({
|
|
@@ -79,7 +25,7 @@ export function HooksManager({
|
|
|
79
25
|
targetScreen,
|
|
80
26
|
plugins,
|
|
81
27
|
startUpHooksData = {},
|
|
82
|
-
}
|
|
28
|
+
}) {
|
|
83
29
|
hooksManagerLogger.addContext({ targetScreen });
|
|
84
30
|
|
|
85
31
|
function logHookEvent(func, message, data) {
|
|
@@ -89,8 +35,7 @@ export function HooksManager({
|
|
|
89
35
|
});
|
|
90
36
|
}
|
|
91
37
|
|
|
92
|
-
const hooksManager
|
|
93
|
-
hooksManager.subscriber = subscriber();
|
|
38
|
+
const hooksManager = subscriber();
|
|
94
39
|
|
|
95
40
|
/**
|
|
96
41
|
* attaches the screen data to the hook object if the hook
|
|
@@ -155,6 +100,15 @@ export function HooksManager({
|
|
|
155
100
|
};
|
|
156
101
|
}
|
|
157
102
|
|
|
103
|
+
/**
|
|
104
|
+
* orders the hooks according to their weight
|
|
105
|
+
* @param {Array<object>} hooks to sort out
|
|
106
|
+
* @returns {Array<object>} sorted hooks
|
|
107
|
+
*/
|
|
108
|
+
function orderHooksByWeight(hooks) {
|
|
109
|
+
return R.sortBy(R.compose(Number, R.prop("weight")), hooks);
|
|
110
|
+
}
|
|
111
|
+
|
|
158
112
|
/**
|
|
159
113
|
* extracts the hooks form the target river. returns null if there are none
|
|
160
114
|
* if there are hooks, gathers all required data and constructs a Hook object
|
|
@@ -163,10 +117,10 @@ export function HooksManager({
|
|
|
163
117
|
* @returns {Array<Hooks>} list of hooks to go through
|
|
164
118
|
*/
|
|
165
119
|
function getHooks(hookType, river) {
|
|
166
|
-
const playerhooks
|
|
120
|
+
const playerhooks = [];
|
|
167
121
|
|
|
168
|
-
if (riverIsPlayer(river
|
|
169
|
-
playerhooks.push(...injectPlayerHooks(hookType
|
|
122
|
+
if (riverIsPlayer(river)) {
|
|
123
|
+
playerhooks.push(...injectPlayerHooks(hookType));
|
|
170
124
|
}
|
|
171
125
|
|
|
172
126
|
let hooks = R.concat(playerhooks, R.pathOr([], ["hooks", hookType], river));
|
|
@@ -176,10 +130,8 @@ export function HooksManager({
|
|
|
176
130
|
const { startUpHooks, setStartUpHooks } = startUpHooksData;
|
|
177
131
|
|
|
178
132
|
if (startUpHooks && startUpHooks !== "in_process") {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
setStartUpHooks("in_process");
|
|
182
|
-
}
|
|
133
|
+
hooks.unshift(...startUpHooks);
|
|
134
|
+
setStartUpHooks("in_process");
|
|
183
135
|
}
|
|
184
136
|
|
|
185
137
|
if (!R.length(hooks)) {
|
|
@@ -206,6 +158,45 @@ export function HooksManager({
|
|
|
206
158
|
)(hooks);
|
|
207
159
|
}
|
|
208
160
|
|
|
161
|
+
/**
|
|
162
|
+
* tells wether the current river is related to a player plugin, or the default player
|
|
163
|
+
* @param {Object} river
|
|
164
|
+
* @returns {boolean}
|
|
165
|
+
*/
|
|
166
|
+
function riverIsPlayer(river) {
|
|
167
|
+
const { screenType, plugin_type } = river;
|
|
168
|
+
|
|
169
|
+
if (screenType || plugin_type) {
|
|
170
|
+
return screenType === "playable" || plugin_type === "player";
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const { type } = river;
|
|
174
|
+
|
|
175
|
+
return R.compose(
|
|
176
|
+
R.propEq("type", "player"),
|
|
177
|
+
R.defaultTo({}),
|
|
178
|
+
R.find(R.propEq("identifier", type))
|
|
179
|
+
)(plugins);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Injects the hooks for the player
|
|
184
|
+
* @param {String} hookType type of hook
|
|
185
|
+
* @returns {Array<Object>}
|
|
186
|
+
*/
|
|
187
|
+
function injectPlayerHooks(_hookType) {
|
|
188
|
+
const playerhooks = R.compose(
|
|
189
|
+
R.sortBy(R.prop("weight")),
|
|
190
|
+
R.map((plugin) => ({
|
|
191
|
+
identifier: plugin.identifier,
|
|
192
|
+
weight: R.path(["module", "weight"], plugin) || 1,
|
|
193
|
+
})),
|
|
194
|
+
R.filter(R.pathEq(["module", "hasPlayerHook"], true))
|
|
195
|
+
)(plugins);
|
|
196
|
+
|
|
197
|
+
return playerhooks;
|
|
198
|
+
}
|
|
199
|
+
|
|
209
200
|
/**
|
|
210
201
|
* tells wether the given hook is the last one or not
|
|
211
202
|
* @param {Hook} hookPlugin
|
|
@@ -218,32 +209,6 @@ export function HooksManager({
|
|
|
218
209
|
return hookPlugin.lastHook;
|
|
219
210
|
}
|
|
220
211
|
|
|
221
|
-
/**
|
|
222
|
-
* flags a hook as succeeded, and pass hook data along
|
|
223
|
-
* @param {Hook} hookPlugin
|
|
224
|
-
* @param {object} payload returned by the hook plugin
|
|
225
|
-
*/
|
|
226
|
-
function completeHook(hookPlugin, payload, callback) {
|
|
227
|
-
logHookEvent(
|
|
228
|
-
hooksManagerLogger.info,
|
|
229
|
-
`completeHook: hook sequence completed successfully: ${hookPlugin["identifier"]}`,
|
|
230
|
-
{
|
|
231
|
-
payload,
|
|
232
|
-
hook: hookPlugin,
|
|
233
|
-
}
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
// eslint-disable-next-line
|
|
237
|
-
// TODO: Temporary hack to pass getLoginProtocol to other plugins to refresh in case token expired, need be deleted later
|
|
238
|
-
delete payload.getLoginProtocol;
|
|
239
|
-
|
|
240
|
-
hookPlugin.setStateAndNotify(HOOKS_EVENTS.COMPLETE, {
|
|
241
|
-
hookPlugin,
|
|
242
|
-
payload,
|
|
243
|
-
callback,
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
212
|
/**
|
|
248
213
|
* creates the callback to invoke in order to proceed to the next hook
|
|
249
214
|
* covers the scenarios of failure & flow blocking
|
|
@@ -344,11 +309,37 @@ export function HooksManager({
|
|
|
344
309
|
|
|
345
310
|
isLastHook(hookPlugin, restOfHooks)
|
|
346
311
|
? completeHook(hookPlugin, payload, callback)
|
|
347
|
-
:
|
|
312
|
+
: handleNextHook(restOfHooks, payload);
|
|
348
313
|
}
|
|
349
314
|
};
|
|
350
315
|
}
|
|
351
316
|
|
|
317
|
+
/**
|
|
318
|
+
* flags a hook as succeeded, and pass hook data along
|
|
319
|
+
* @param {Hook} hookPlugin
|
|
320
|
+
* @param {object} payload returned by the hook plugin
|
|
321
|
+
*/
|
|
322
|
+
function completeHook(hookPlugin, payload, callback) {
|
|
323
|
+
logHookEvent(
|
|
324
|
+
hooksManagerLogger.info,
|
|
325
|
+
`completeHook: hook sequence completed successfully: ${hookPlugin["identifier"]}`,
|
|
326
|
+
{
|
|
327
|
+
payload,
|
|
328
|
+
hook: hookPlugin,
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
// eslint-disable-next-line
|
|
333
|
+
// TODO: Temporary hack to pass getLoginProtocol to other plugins to refresh in case token expired, need be deleted later
|
|
334
|
+
delete payload.getLoginProtocol;
|
|
335
|
+
|
|
336
|
+
hookPlugin.setStateAndNotify(HOOKS_EVENTS.COMPLETE, {
|
|
337
|
+
hookPlugin,
|
|
338
|
+
payload,
|
|
339
|
+
callback,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
|
|
352
343
|
/**
|
|
353
344
|
* presents a screen hook by triggering an event invoking the handler with
|
|
354
345
|
* the appropriate route & payload
|
|
@@ -385,6 +376,9 @@ export function HooksManager({
|
|
|
385
376
|
|
|
386
377
|
/**
|
|
387
378
|
* executes a headless hook
|
|
379
|
+
* @param {Hook} hookPlugin to present
|
|
380
|
+
* @param {object} payload to pass to the hook module
|
|
381
|
+
* @param {function} callback to invoke when the hook is successful
|
|
388
382
|
*/
|
|
389
383
|
hooksManager.executeHook = function (hookPlugin, payload, callback) {
|
|
390
384
|
logHookEvent(
|
|
@@ -450,6 +444,23 @@ export function HooksManager({
|
|
|
450
444
|
}
|
|
451
445
|
};
|
|
452
446
|
|
|
447
|
+
/**
|
|
448
|
+
* handles the next hook in the list of provided hooks, passing the payload along
|
|
449
|
+
* @param {Array<Hook>} hooks to process
|
|
450
|
+
* @param {object} payload to pass to the hook
|
|
451
|
+
*/
|
|
452
|
+
function handleNextHook(hooks, payload) {
|
|
453
|
+
const [hookPlugin, ...restOfHooks] = orderHooksByWeight(hooks);
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Commenting out part of the code which is trying to run the next hook
|
|
457
|
+
* in parallel - it's not in use, and it's creating unexpected side
|
|
458
|
+
* effects
|
|
459
|
+
* */
|
|
460
|
+
|
|
461
|
+
hookPlugin.execute(payload, hookCallback(hookPlugin, restOfHooks, payload));
|
|
462
|
+
}
|
|
463
|
+
|
|
453
464
|
/**
|
|
454
465
|
* function exposes on the hooks manager to trigger the handling of the hooks for
|
|
455
466
|
* the given targetScreen
|
|
@@ -471,9 +482,9 @@ export function HooksManager({
|
|
|
471
482
|
}
|
|
472
483
|
);
|
|
473
484
|
|
|
474
|
-
|
|
485
|
+
handleNextHook(preloadHooks, payload);
|
|
475
486
|
} else {
|
|
476
|
-
hooksManager.
|
|
487
|
+
hooksManager.invokeHandler(HOOKS_EVENTS.COMPLETE, {
|
|
477
488
|
hookPlugin: { lastHook: true },
|
|
478
489
|
payload,
|
|
479
490
|
});
|
|
@@ -482,5 +493,5 @@ export function HooksManager({
|
|
|
482
493
|
return hooksManager;
|
|
483
494
|
};
|
|
484
495
|
|
|
485
|
-
return hooksManager
|
|
496
|
+
return hooksManager;
|
|
486
497
|
}
|