@applicaster/zapp-react-native-utils 16.0.0-rc.1 → 16.0.0-rc.100
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 +57 -12
- package/actionsExecutor/ActionExecutorContext.tsx +113 -314
- package/actionsExecutor/__tests__/ActionExecutor.test.ts +71 -0
- package/actionsExecutor/__tests__/feedDecorator.test.ts +61 -0
- package/actionsExecutor/actions/__tests__/dismissBottomSheet.test.ts +25 -0
- package/actionsExecutor/actions/__tests__/goBack.test.ts +62 -0
- package/actionsExecutor/actions/__tests__/goHome.test.ts +19 -0
- package/actionsExecutor/actions/__tests__/loadItemsFromSource.test.ts +88 -0
- package/actionsExecutor/actions/__tests__/navigateToScreen.test.ts +133 -0
- package/actionsExecutor/actions/__tests__/openBottomSheet.customContent.test.ts +76 -0
- package/actionsExecutor/actions/__tests__/openBottomSheet.inlineItems.test.ts +300 -0
- package/actionsExecutor/actions/__tests__/presentScreen.test.ts +127 -0
- package/actionsExecutor/actions/__tests__/showAlert.test.ts +49 -0
- package/actionsExecutor/actions/__tests__/showToast.test.ts +88 -0
- package/actionsExecutor/actions/appRestart.ts +24 -0
- package/actionsExecutor/actions/confirmDialog.ts +53 -0
- package/actionsExecutor/actions/dismissBottomSheet.ts +23 -0
- package/actionsExecutor/actions/goBack.ts +60 -0
- package/actionsExecutor/actions/goHome.ts +31 -0
- package/actionsExecutor/actions/index.ts +42 -0
- package/actionsExecutor/actions/localStorageRemove.ts +27 -0
- package/actionsExecutor/actions/localStorageSet.ts +28 -0
- package/actionsExecutor/actions/localStorageToggleFlag.ts +28 -0
- package/actionsExecutor/actions/navigateToScreen.ts +137 -0
- package/actionsExecutor/actions/openBottomSheet.ts +338 -0
- package/actionsExecutor/actions/presentScreen.ts +78 -0
- package/actionsExecutor/actions/refreshComponent.ts +85 -0
- package/actionsExecutor/actions/screenSetVariable.ts +35 -0
- package/actionsExecutor/actions/screenToggleFlag.ts +38 -0
- package/actionsExecutor/actions/sendCloudEvent.ts +93 -0
- package/actionsExecutor/actions/sessionStorageRemove.ts +19 -0
- package/actionsExecutor/actions/sessionStorageSet.ts +20 -0
- package/actionsExecutor/actions/sessionStorageToggleFlag.ts +15 -0
- package/actionsExecutor/actions/showAlert.ts +51 -0
- package/actionsExecutor/actions/showToast.ts +87 -0
- package/actionsExecutor/actions/switchLayout.ts +40 -0
- package/actionsExecutor/consts.ts +27 -0
- package/actionsExecutor/feedDecorator.ts +6 -6
- package/actionsExecutor/types.ts +59 -0
- package/analyticsUtils/AnalyticsEvents/sendMenuClickEvent.ts +2 -2
- package/analyticsUtils/PlayerAnalyticsManager.ts +12 -2
- package/analyticsUtils/__tests__/analyticsMapper.test.ts +35 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testACP_events.json +1 -1
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testBlockUnlistedParams_rules.json +1 -1
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEmptyRenameKeepsName_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEmptyRenameKeepsName_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEventRegex_events.json +3 -9
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testIgnoreOrdering_events.json +18 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testIgnoreOrdering_rules.json +16 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexEventNoFallback_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexEventNoFallback_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexMultiGroupRename_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexMultiGroupRename_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexNonNamedFullMatch_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexNonNamedFullMatch_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/index.js +20 -0
- package/analyticsUtils/analyticsMapper.ts +4 -1
- package/analyticsUtils/playerAnalyticsTracker.ts +26 -3
- package/appUtils/HooksManager/index.ts +15 -17
- package/appUtils/contextKeysManager/__tests__/getKey/failure.test.ts +1 -1
- package/appUtils/contextKeysManager/__tests__/removeKey/failure.test.ts +1 -1
- package/appUtils/contextKeysManager/__tests__/setKey/failure/invalidKey.test.ts +4 -4
- package/appUtils/contextKeysManager/index.ts +1 -1
- package/appUtils/contextKeysManager/utils/index.ts +38 -25
- package/appUtils/platform/platformUtils.ts +11 -0
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +142 -59
- package/appUtils/playerManager/OverlayObserver/__tests__/getUpcomingQueue.test.ts +67 -0
- package/appUtils/playerManager/OverlayObserver/__tests__/liveContent.test.ts +205 -0
- package/appUtils/playerManager/OverlayObserver/__tests__/utils.test.ts +56 -0
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.android.tv.ts +4 -0
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.ios.tv.ts +4 -0
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.ts +24 -0
- package/appUtils/playerManager/OverlayObserver/getUpcomingQueue.web.ts +4 -0
- package/appUtils/playerManager/OverlayObserver/utils.ts +51 -20
- package/appUtils/playerManager/__tests__/playerContent.test.ts +403 -0
- package/appUtils/playerManager/__tests__/playerFactory.test.ts +150 -0
- package/appUtils/playerManager/__tests__/playerNative.test.ts +38 -0
- package/appUtils/playerManager/__tests__/usePlayerContent.test.tsx +64 -0
- package/appUtils/playerManager/{conts.ts → const.ts} +20 -0
- package/appUtils/playerManager/index.ts +1 -1
- package/appUtils/playerManager/player.ts +115 -3
- package/appUtils/playerManager/playerFactory.ts +18 -35
- package/appUtils/playerManager/playerNative.ts +6 -4
- package/appUtils/playerManager/usePlayerContent.tsx +43 -0
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +1 -1
- package/appUtils/playerManager/userLanguagePreference.ts +1 -1
- package/arrayUtils/__tests__/{anyThruthy.test.ts → anyTruthy.test.ts} +8 -0
- package/arrayUtils/__tests__/arrayUtils.test.ts +165 -108
- package/arrayUtils/__tests__/isEmptyArray.test.ts +11 -0
- package/arrayUtils/__tests__/isFilledArray.test.ts +12 -0
- package/arrayUtils/__tests__/isFirst.test.ts +17 -0
- package/arrayUtils/__tests__/isIndexInRange.test.ts +14 -0
- package/arrayUtils/__tests__/isLast.test.ts +31 -0
- package/arrayUtils/__tests__/makeListOf.test.ts +31 -0
- package/arrayUtils/__tests__/makeListOfIndexes.test.ts +20 -0
- package/arrayUtils/__tests__/reorderByIds.test.ts +63 -0
- package/arrayUtils/__tests__/sample.test.ts +61 -0
- package/arrayUtils/index.ts +119 -20
- package/bottomSheet/__tests__/scrollContext.test.tsx +35 -0
- package/bottomSheet/index.ts +17 -0
- package/cellUtils/index.ts +33 -8
- package/colorUtils/__tests__/isTransparentColor.test.ts +76 -0
- package/colorUtils/__tests__/isValidColor.test.ts +70 -0
- package/colorUtils/index.ts +50 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +21 -0
- package/configurationUtils/__tests__/modalBlocksParser.test.ts +269 -0
- package/configurationUtils/manifestKeyParser.ts +50 -10
- package/configurationUtils/modalBlocksParser.ts +214 -0
- package/entryActions/__tests__/buildEntryActions.test.ts +235 -0
- package/entryActions/aliasPresentation.ts +108 -0
- package/entryActions/buildEntryActions.ts +167 -0
- package/entryActions/index.ts +15 -0
- package/entryActions/types.ts +39 -0
- package/manifestUtils/__tests__/player.audioControls.test.js +158 -0
- package/manifestUtils/_internals/index.js +14 -3
- package/manifestUtils/defaultManifestConfigurations/generalContent.js +41 -0
- package/manifestUtils/defaultManifestConfigurations/player.js +349 -20
- package/manifestUtils/fieldUtils/__tests__/fieldUtils.test.js +84 -0
- package/manifestUtils/fieldUtils/index.js +125 -0
- package/manifestUtils/index.js +4 -1
- package/manifestUtils/keys.js +9 -0
- package/manifestUtils/mobileAction/button/index.js +16 -0
- package/manifestUtils/mobileAction/container/index.js +3 -1
- package/manifestUtils/mobileAction/groups/defaults.js +3 -1
- package/manifestUtils/modalBlocks.js +304 -0
- package/manifestUtils/platformIsTV.js +1 -0
- package/modalState/ContentViewModel.ts +113 -0
- package/modalState/EditableCollection.ts +17 -0
- package/modalState/EditableCollectionRegistry.ts +51 -0
- package/modalState/ModalOrchestrator.ts +212 -0
- package/modalState/RemoteEditableCollection.ts +235 -0
- package/modalState/__tests__/ContentViewModel.editable.test.ts +69 -0
- package/modalState/__tests__/ContentViewModel.test.ts +165 -0
- package/modalState/__tests__/EditableCollectionRegistry.test.ts +112 -0
- package/modalState/__tests__/ModalOrchestrator.phase3.test.ts +63 -0
- package/modalState/__tests__/RemoteEditableCollection.test.ts +415 -0
- package/modalState/__tests__/index.test.ts +30 -1
- package/modalState/__tests__/useBottomSheetContent.test.ts +349 -0
- package/modalState/__tests__/useModalStoreState.test.ts +142 -0
- package/modalState/index.ts +35 -83
- package/modalState/store.ts +109 -0
- package/modalState/types.ts +162 -0
- package/modalState/useBottomSheetContent.ts +109 -0
- package/numberUtils/__tests__/isMinusZero.test.ts +20 -0
- package/numberUtils/__tests__/isZero.test.ts +27 -0
- package/numberUtils/__tests__/requireNumber.test.ts +50 -0
- package/numberUtils/__tests__/toNumber.test.ts +27 -0
- package/numberUtils/__tests__/toNumberWithDefault.test.ts +64 -0
- package/numberUtils/__tests__/toNumberWithDefaultZero.test.ts +48 -0
- package/numberUtils/index.ts +27 -8
- package/package.json +2 -2
- package/pipesUtils/__tests__/buildUrlWithQuery.test.ts +33 -0
- package/pipesUtils/__tests__/withPipesEndpoint.test.tsx +56 -0
- package/pipesUtils/index.ts +1 -0
- package/pipesUtils/withPipesEndpoint.tsx +54 -0
- package/playerUtils/__tests__/contentDataKeys.test.ts +297 -0
- package/playerUtils/__tests__/resolvePlayerActions.test.ts +138 -0
- package/playerUtils/__tests__/resolvePlayerTitleSubtitle.test.ts +180 -0
- package/playerUtils/contentDataKeys.ts +134 -0
- package/playerUtils/index.ts +58 -15
- package/playerUtils/isAudioItem.ts +26 -0
- package/playerUtils/resolvePlayerActions.ts +71 -0
- package/playerUtils/resolvePlayerTitleSubtitle.ts +76 -0
- package/pluginUtils/__tests__/pluginUtils.test.js +32 -0
- package/pluginUtils/index.ts +29 -0
- package/reactHooks/actions/index.ts +117 -2
- package/reactHooks/cell-click/__tests__/index.test.js +64 -0
- package/reactHooks/cell-click/index.ts +39 -24
- package/reactHooks/feed/__mocks__/useMarkPipesDataStale.ts +4 -0
- package/reactHooks/feed/__tests__/useInflatedUrl.test.tsx +25 -0
- package/reactHooks/feed/index.ts +5 -1
- package/reactHooks/feed/useBatchLoading.ts +9 -1
- package/reactHooks/feed/{usePipesCacheReset.ts → useMarkPipesDataStale.ts} +12 -4
- package/reactHooks/index.ts +2 -0
- package/reactHooks/layout/index.ts +1 -1
- package/reactHooks/navigation/__mocks__/index.ts +4 -0
- package/reactHooks/navigation/__tests__/index.test.tsx +176 -1
- package/reactHooks/navigation/__tests__/useIsScreenActive.test.ts +42 -0
- package/reactHooks/navigation/__tests__/usePresentScreen.test.ts +154 -0
- package/reactHooks/navigation/index.ts +3 -1
- package/reactHooks/navigation/useIsScreenActive.ts +29 -8
- package/reactHooks/navigation/usePresentScreen.ts +157 -0
- package/reactHooks/navigation/useRoute.ts +22 -5
- package/reactHooks/screen/__tests__/useIsStandaloneFullscreen.test.ts +114 -0
- package/reactHooks/screen/index.ts +2 -0
- package/reactHooks/screen/useIsStandaloneFullscreen.ts +12 -0
- package/reactHooks/state/useComponentScreenState.ts +1 -1
- package/reactHooks/usePluginConfiguration.ts +4 -1
- package/reactHooks/utils/__tests__/index.test.js +22 -2
- package/reactHooks/utils/index.ts +13 -2
- package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +22 -4
- package/riverComponetsMeasurementProvider/index.tsx +12 -8
- package/stringUtils/__tests__/stringUtils.test.js +42 -0
- package/stringUtils/index.ts +2 -2
- package/uiActionsRegistrator/__tests__/resolveActionIdentifiers.test.ts +93 -0
- package/uiActionsRegistrator/__tests__/subscribe.test.ts +107 -0
- package/uiActionsRegistrator/__tests__/usableActionItems.test.ts +52 -0
- package/uiActionsRegistrator/index.ts +25 -0
- package/uiActionsRegistrator/registry.ts +335 -0
- package/uiActionsRegistrator/resolveActionIdentifiers.ts +100 -0
- package/uiActionsRegistrator/usableActionItems.ts +66 -0
- package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +1 -1
- package/zappFrameworkUtils/__tests__/localStorageHelper.test.ts +146 -0
- package/zappFrameworkUtils/localStorageHelper.ts +19 -15
- package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +0 -56
- package/playerUtils/__tests__/getPlayerActionButtons.test.ts +0 -54
- package/playerUtils/getPlayerActionButtons.ts +0 -17
- package/reactHooks/feed/__mocks__/usePipesCacheReset.ts +0 -1
- /package/reactHooks/actions/__tests__/{index.test.js → index.test.tsx} +0 -0
|
@@ -6,9 +6,9 @@ import { postAnalyticEvent } from "../manager";
|
|
|
6
6
|
import { ANALYTICS_CORE_EVENTS } from "../events";
|
|
7
7
|
|
|
8
8
|
type AnalyticsDefaultHelperProperties = {
|
|
9
|
-
analyticsScreenData
|
|
9
|
+
analyticsScreenData?: AnalyticsScreenProperties;
|
|
10
10
|
extraProps: any;
|
|
11
|
-
props;
|
|
11
|
+
props?: any;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
export const sendMenuClickEvent = ({
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "../appUtils/playerManager";
|
|
9
9
|
import { Player } from "../appUtils/playerManager/player";
|
|
10
10
|
import { AnalyticPlayerListener } from "./AnalyticPlayerListener";
|
|
11
|
-
import { PlayerRole } from "../appUtils/playerManager/
|
|
11
|
+
import { PlayerRole } from "../appUtils/playerManager/const";
|
|
12
12
|
|
|
13
13
|
enum PlayerAnalyticsTrackerType {
|
|
14
14
|
PlayerAnalyticsTracker = "PlayerAnalyticsTracker",
|
|
@@ -23,6 +23,15 @@ class PlayerAnalyticsTrackerFactory {
|
|
|
23
23
|
return new PlayerAnalyticsTracker();
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
+
|
|
27
|
+
onPlayerRegistered(tracker: PlayerAnalyticsTrackerI, player: Player) {
|
|
28
|
+
tracker.setPlayer(player);
|
|
29
|
+
tracker.onPlayerPresented();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
onPlayerUnRegistered(tracker?: PlayerAnalyticsTrackerI) {
|
|
33
|
+
tracker?.onPlayerClosed();
|
|
34
|
+
}
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
export class PlayerAnalyticsManager implements PlayerLifecycleListener {
|
|
@@ -70,7 +79,7 @@ export class PlayerAnalyticsManager implements PlayerLifecycleListener {
|
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
const tracker = this.getTracker(player.playerId);
|
|
73
|
-
|
|
82
|
+
this.trackerFactory.onPlayerRegistered(tracker, player);
|
|
74
83
|
|
|
75
84
|
const analyticsListener = new AnalyticPlayerListener({
|
|
76
85
|
analyticsTracker: tracker,
|
|
@@ -84,6 +93,7 @@ export class PlayerAnalyticsManager implements PlayerLifecycleListener {
|
|
|
84
93
|
};
|
|
85
94
|
|
|
86
95
|
onUnRegistered = (player: Player) => {
|
|
96
|
+
this.trackerFactory.onPlayerUnRegistered(this.trackers[player.playerId]);
|
|
87
97
|
player.removeListener(AnalyticPlayerListener.analyticsListenerID);
|
|
88
98
|
delete this.trackers[player.playerId];
|
|
89
99
|
};
|
|
@@ -74,4 +74,39 @@ describe("Analytics Mapper", () => {
|
|
|
74
74
|
const rules = fixtures.ACPEventRules;
|
|
75
75
|
await setConfigRunMapTest(rules, fixtures.ACPEventEvents);
|
|
76
76
|
});
|
|
77
|
+
|
|
78
|
+
it("Does not let an ignore rule short-circuit later events", async () => {
|
|
79
|
+
await setConfigRunMapTest(
|
|
80
|
+
fixtures.ignoreOrderingRules,
|
|
81
|
+
fixtures.ignoreOrderingEvents
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("Keeps the original name when rename is empty", async () => {
|
|
86
|
+
await setConfigRunMapTest(
|
|
87
|
+
fixtures.emptyRenameRules,
|
|
88
|
+
fixtures.emptyRenameEvents
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("Renames via a regex with no named groups", async () => {
|
|
93
|
+
await setConfigRunMapTest(
|
|
94
|
+
fixtures.regexNonNamedFullMatchRules,
|
|
95
|
+
fixtures.regexNonNamedFullMatchEvents
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("Substitutes every named group in a regex rename", async () => {
|
|
100
|
+
await setConfigRunMapTest(
|
|
101
|
+
fixtures.regexMultiGroupRenameRules,
|
|
102
|
+
fixtures.regexMultiGroupRenameEvents
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("Does not fall back to event match when a regex rule does not match", async () => {
|
|
107
|
+
await setConfigRunMapTest(
|
|
108
|
+
fixtures.regexEventNoFallbackRules,
|
|
109
|
+
fixtures.regexEventNoFallbackEvents
|
|
110
|
+
);
|
|
111
|
+
});
|
|
77
112
|
});
|
|
@@ -2,17 +2,11 @@
|
|
|
2
2
|
{
|
|
3
3
|
"first": {
|
|
4
4
|
"name": "Screen viewed: Ads & redirects",
|
|
5
|
-
"params": {
|
|
6
|
-
"ignored_param": "removed_value",
|
|
7
|
-
"kept_param": "kept_value"
|
|
8
|
-
}
|
|
5
|
+
"params": {}
|
|
9
6
|
},
|
|
10
7
|
"second": {
|
|
11
8
|
"name": "Screen Ads & redirects",
|
|
12
|
-
"params": {
|
|
13
|
-
"ignored_param": "removed_value",
|
|
14
|
-
"kept_param": "kept_value"
|
|
15
|
-
}
|
|
9
|
+
"params": {}
|
|
16
10
|
}
|
|
17
11
|
}
|
|
18
|
-
]
|
|
12
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rules": [
|
|
3
|
+
{
|
|
4
|
+
"event": "player_presented",
|
|
5
|
+
"ignore": true,
|
|
6
|
+
"strategy": "allowUnlisted"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"event": "screen_view",
|
|
10
|
+
"ignore": false,
|
|
11
|
+
"rename": "page_view",
|
|
12
|
+
"strategy": "allowUnlisted"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"strategy": "allowUnlisted"
|
|
16
|
+
}
|
|
@@ -14,6 +14,16 @@ import blockUnlistedEventEvents from "./analytics_mapper_testBlockUnlistedEvents
|
|
|
14
14
|
import blockUnlistedEventRules from "./analytics_mapper_testBlockUnlistedEvents_rules.json";
|
|
15
15
|
import ACPEventEvents from "./analytics_mapper_testACP_events.json";
|
|
16
16
|
import ACPEventRules from "./analytics_mapper_testACP_rules.json";
|
|
17
|
+
import emptyRenameRules from "./analytics_mapper_testEmptyRenameKeepsName_rules.json";
|
|
18
|
+
import emptyRenameEvents from "./analytics_mapper_testEmptyRenameKeepsName_events.json";
|
|
19
|
+
import ignoreOrderingRules from "./analytics_mapper_testIgnoreOrdering_rules.json";
|
|
20
|
+
import ignoreOrderingEvents from "./analytics_mapper_testIgnoreOrdering_events.json";
|
|
21
|
+
import regexEventNoFallbackRules from "./analytics_mapper_testRegexEventNoFallback_rules.json";
|
|
22
|
+
import regexEventNoFallbackEvents from "./analytics_mapper_testRegexEventNoFallback_events.json";
|
|
23
|
+
import regexMultiGroupRenameRules from "./analytics_mapper_testRegexMultiGroupRename_rules.json";
|
|
24
|
+
import regexMultiGroupRenameEvents from "./analytics_mapper_testRegexMultiGroupRename_events.json";
|
|
25
|
+
import regexNonNamedFullMatchRules from "./analytics_mapper_testRegexNonNamedFullMatch_rules.json";
|
|
26
|
+
import regexNonNamedFullMatchEvents from "./analytics_mapper_testRegexNonNamedFullMatch_events.json";
|
|
17
27
|
|
|
18
28
|
export const fixtures = {
|
|
19
29
|
renameRules,
|
|
@@ -32,4 +42,14 @@ export const fixtures = {
|
|
|
32
42
|
blockUnlistedEventRules,
|
|
33
43
|
ACPEventEvents,
|
|
34
44
|
ACPEventRules,
|
|
45
|
+
emptyRenameRules,
|
|
46
|
+
emptyRenameEvents,
|
|
47
|
+
ignoreOrderingRules,
|
|
48
|
+
ignoreOrderingEvents,
|
|
49
|
+
regexEventNoFallbackRules,
|
|
50
|
+
regexEventNoFallbackEvents,
|
|
51
|
+
regexMultiGroupRenameRules,
|
|
52
|
+
regexMultiGroupRenameEvents,
|
|
53
|
+
regexNonNamedFullMatchRules,
|
|
54
|
+
regexNonNamedFullMatchEvents,
|
|
35
55
|
};
|
|
@@ -76,7 +76,10 @@ class StateHolder {
|
|
|
76
76
|
delete this.pluckedParams[prefix];
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
// Stringify so values match the native iOS/Android mappers (which coerce
|
|
80
|
+
// analyticsCustomProperties values to strings) — keeps GA4 data consistent
|
|
81
|
+
// across web/LG/Samsung and native platforms.
|
|
82
|
+
return this._cap?.[suffix]?.toString() ?? null;
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
private async getFromLocalAndSession(
|
|
@@ -4,8 +4,14 @@ import { isTrue } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
|
4
4
|
import { postAnalyticEvent } from "./manager";
|
|
5
5
|
import { isLive } from "../playerUtils";
|
|
6
6
|
import { extensionsEvents } from "./AnalyticsEvents/helper";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
AD_EVENT,
|
|
9
|
+
EVENT_TYPES,
|
|
10
|
+
GENERAL_EVENT,
|
|
11
|
+
PLAYER_DISPLAY_STATES,
|
|
12
|
+
} from "./events";
|
|
8
13
|
import { Player } from "../appUtils/playerManager/player";
|
|
14
|
+
import { isNil } from "@applicaster/zapp-react-native-utils/utils";
|
|
9
15
|
|
|
10
16
|
export interface PlayerAnalyticsTrackerI {
|
|
11
17
|
handleAnalyticEvent(
|
|
@@ -13,6 +19,8 @@ export interface PlayerAnalyticsTrackerI {
|
|
|
13
19
|
eventData?: QuickBrickPlayer.EventData
|
|
14
20
|
): void;
|
|
15
21
|
setPlayer(player: Player): void;
|
|
22
|
+
onPlayerPresented(): void;
|
|
23
|
+
onPlayerClosed(): void;
|
|
16
24
|
}
|
|
17
25
|
|
|
18
26
|
export class PlayerAnalyticsTracker implements PlayerAnalyticsTrackerI {
|
|
@@ -26,6 +34,15 @@ export class PlayerAnalyticsTracker implements PlayerAnalyticsTrackerI {
|
|
|
26
34
|
this.player = player;
|
|
27
35
|
}
|
|
28
36
|
|
|
37
|
+
onPlayerPresented() {
|
|
38
|
+
this.handleAnalyticEvent(GENERAL_EVENT.player_presented);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
onPlayerClosed() {
|
|
42
|
+
this.handleAnalyticEvent(GENERAL_EVENT.session_end);
|
|
43
|
+
this.handleAnalyticEvent(GENERAL_EVENT.player_closed);
|
|
44
|
+
}
|
|
45
|
+
|
|
29
46
|
isAdBreak(event: string): boolean {
|
|
30
47
|
const adBreakEvents = [
|
|
31
48
|
AD_EVENT.ad_break_start,
|
|
@@ -180,7 +197,8 @@ export class PlayerAnalyticsTracker implements PlayerAnalyticsTrackerI {
|
|
|
180
197
|
this.entry?.extensions?.free || this.entry?.extensions?.isFree;
|
|
181
198
|
|
|
182
199
|
const title = this.entry?.title;
|
|
183
|
-
const
|
|
200
|
+
const isStreamLive = isLive(this.entry);
|
|
201
|
+
const streamType = isStreamLive ? "live" : "vod"; // Todo: determine other types, channel, podcast, aod
|
|
184
202
|
|
|
185
203
|
const currentPosition = this.getCurrentPosition(
|
|
186
204
|
event,
|
|
@@ -201,6 +219,7 @@ export class PlayerAnalyticsTracker implements PlayerAnalyticsTrackerI {
|
|
|
201
219
|
);
|
|
202
220
|
|
|
203
221
|
const playerState = this.getPlayerState();
|
|
222
|
+
const playerType = this.player?.playerPluginId;
|
|
204
223
|
|
|
205
224
|
const analyticsCustomProperties = extensionsEvents(this.entry?.extensions);
|
|
206
225
|
|
|
@@ -210,7 +229,11 @@ export class PlayerAnalyticsTracker implements PlayerAnalyticsTrackerI {
|
|
|
210
229
|
name: title,
|
|
211
230
|
media_type: mediaType,
|
|
212
231
|
stream_type: streamType,
|
|
213
|
-
|
|
232
|
+
player_type: playerType,
|
|
233
|
+
// We do not pass duration for live streams anymore (it's now seekableDuration),
|
|
234
|
+
// but we can't mark it as optional in Analytics Mapper yet,
|
|
235
|
+
// so we set it to -1 for live streams
|
|
236
|
+
duration: isStreamLive && isNil(mediaDuration) ? -1 : mediaDuration,
|
|
214
237
|
current_position: currentPosition,
|
|
215
238
|
player_state: playerState,
|
|
216
239
|
stream_format: contentType,
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
2
|
|
|
3
3
|
import { subscriber } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
4
|
-
import {
|
|
5
|
-
QUICK_BRICK_EVENTS,
|
|
6
|
-
sendQuickBrickEvent,
|
|
7
|
-
} from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
8
|
-
|
|
9
4
|
import { Hook } from "./Hook";
|
|
10
5
|
import { HOOKS_EVENTS, HOOKS_TYPE } from "./constants";
|
|
11
6
|
|
|
7
|
+
import { platformToBackground } from "../platform";
|
|
8
|
+
|
|
12
9
|
import { hooksManagerLogger } from "./logger";
|
|
13
10
|
import { HookManager, HookManagerArgs } from "./types";
|
|
14
11
|
import {
|
|
@@ -90,7 +87,7 @@ export function HooksManager({
|
|
|
90
87
|
}: HookManagerArgs): HookManager {
|
|
91
88
|
hooksManagerLogger.addContext({ targetScreenId: targetScreen.id });
|
|
92
89
|
|
|
93
|
-
function logHookEvent(func, message, data) {
|
|
90
|
+
function logHookEvent(func, message, data = {}) {
|
|
94
91
|
func({
|
|
95
92
|
message,
|
|
96
93
|
data: __DEV__ ? data : null,
|
|
@@ -347,14 +344,10 @@ export function HooksManager({
|
|
|
347
344
|
`hookCallback: send app to background, cancelled flow blocker hook ${hookPlugin.identifier} on home screen`,
|
|
348
345
|
{
|
|
349
346
|
payload,
|
|
350
|
-
hook: hookPlugin,
|
|
351
347
|
}
|
|
352
348
|
);
|
|
353
349
|
|
|
354
|
-
|
|
355
|
-
sendQuickBrickEvent(QUICK_BRICK_EVENTS.MOVE_APP_TO_BACKGROUND, {
|
|
356
|
-
MOVE_APP_TO_BACKGROUND: true,
|
|
357
|
-
});
|
|
350
|
+
platformToBackground();
|
|
358
351
|
}
|
|
359
352
|
} else {
|
|
360
353
|
logHookEvent(
|
|
@@ -362,17 +355,13 @@ export function HooksManager({
|
|
|
362
355
|
`hookCallback: hook successfully finished: ${hookPlugin.identifier}`,
|
|
363
356
|
{
|
|
364
357
|
payload,
|
|
365
|
-
hook: hookPlugin,
|
|
366
358
|
}
|
|
367
359
|
);
|
|
368
360
|
|
|
369
361
|
if (!callback) {
|
|
370
362
|
logHookEvent(
|
|
371
|
-
hooksManagerLogger.
|
|
372
|
-
`hookCallback: ${hookPlugin.identifier} is missing \`callback\`, using hookCallback(default one)
|
|
373
|
-
{
|
|
374
|
-
hookPlugin,
|
|
375
|
-
}
|
|
363
|
+
hooksManagerLogger.debug,
|
|
364
|
+
`hookCallback: ${hookPlugin.identifier} is missing \`callback\`, using hookCallback(default one)`
|
|
376
365
|
);
|
|
377
366
|
|
|
378
367
|
callback = hookCallback;
|
|
@@ -509,6 +498,15 @@ export function HooksManager({
|
|
|
509
498
|
presentUI
|
|
510
499
|
);
|
|
511
500
|
} catch (e) {
|
|
501
|
+
// Without this the failure is invisible: the hook stops right after the
|
|
502
|
+
// "Executing hook" line, with nothing in the log explaining why and no
|
|
503
|
+
// remaining hook ever running.
|
|
504
|
+
logHookEvent(
|
|
505
|
+
hooksManagerLogger.error,
|
|
506
|
+
`runInBackground: hook ${hookPlugin.identifier} threw: ${e?.message}`,
|
|
507
|
+
{ hook: hookPlugin, payload, error: e, stack: e?.stack }
|
|
508
|
+
);
|
|
509
|
+
|
|
512
510
|
hookPlugin.setStateAndNotify(HOOKS_EVENTS.ERROR, {
|
|
513
511
|
error: e,
|
|
514
512
|
hookPlugin,
|
|
@@ -46,7 +46,7 @@ describe("Context Keys Manager - getKey", () => {
|
|
|
46
46
|
|
|
47
47
|
expect(mockedLogger.warn).toHaveBeenCalledWith({
|
|
48
48
|
message:
|
|
49
|
-
"Provided key is not valid -
|
|
49
|
+
"Provided key is not valid - expecting an object with namespace and key properties",
|
|
50
50
|
data: { key: invalidKey },
|
|
51
51
|
});
|
|
52
52
|
|
|
@@ -47,7 +47,7 @@ describe("Context Keys Manager - removeKey", () => {
|
|
|
47
47
|
|
|
48
48
|
expect(mockedLogger.warn).toHaveBeenCalledWith({
|
|
49
49
|
message:
|
|
50
|
-
"Provided key is not valid -
|
|
50
|
+
"Provided key is not valid - expecting an object with namespace and key properties",
|
|
51
51
|
data: { key },
|
|
52
52
|
});
|
|
53
53
|
|
|
@@ -48,7 +48,7 @@ describe("Context Keys Manager - setKey", () => {
|
|
|
48
48
|
|
|
49
49
|
expect(mockedLogger.warn).toHaveBeenCalledWith({
|
|
50
50
|
message:
|
|
51
|
-
"Provided key is not valid -
|
|
51
|
+
"Provided key is not valid - expecting an object with namespace and key properties",
|
|
52
52
|
data: { key },
|
|
53
53
|
});
|
|
54
54
|
|
|
@@ -105,7 +105,7 @@ describe("Context Keys Manager - setKey", () => {
|
|
|
105
105
|
|
|
106
106
|
expect(mockedLogger.warn).toHaveBeenCalledWith({
|
|
107
107
|
message:
|
|
108
|
-
"Provided key is not valid -
|
|
108
|
+
"Provided key is not valid - expecting an object with namespace and key properties",
|
|
109
109
|
data: { key },
|
|
110
110
|
});
|
|
111
111
|
|
|
@@ -162,7 +162,7 @@ describe("Context Keys Manager - setKey", () => {
|
|
|
162
162
|
|
|
163
163
|
expect(mockedLogger.warn).toHaveBeenCalledWith({
|
|
164
164
|
message:
|
|
165
|
-
"Provided key is not valid -
|
|
165
|
+
"Provided key is not valid - expecting an object with namespace and key properties",
|
|
166
166
|
data: { key },
|
|
167
167
|
});
|
|
168
168
|
|
|
@@ -217,7 +217,7 @@ describe("Context Keys Manager - setKey", () => {
|
|
|
217
217
|
|
|
218
218
|
expect(mockedLogger.warn).toHaveBeenCalledWith({
|
|
219
219
|
message:
|
|
220
|
-
"Provided key is not valid -
|
|
220
|
+
"Provided key is not valid - expecting an object with namespace and key properties",
|
|
221
221
|
data: { key },
|
|
222
222
|
});
|
|
223
223
|
|
|
@@ -109,7 +109,7 @@ export class ContextKeysManager {
|
|
|
109
109
|
if (!keyIsValid(parsedKey)) {
|
|
110
110
|
this._logger.warn({
|
|
111
111
|
message:
|
|
112
|
-
"Provided key is not valid -
|
|
112
|
+
"Provided key is not valid - expecting an object with namespace and key properties",
|
|
113
113
|
data: { key },
|
|
114
114
|
});
|
|
115
115
|
|
|
@@ -1,40 +1,53 @@
|
|
|
1
|
-
import * as R from "ramda";
|
|
2
1
|
import { DEFAULT_NAMESPACE } from "../consts";
|
|
3
2
|
import { KeyName, KeyNameObj } from "../index";
|
|
4
3
|
|
|
5
|
-
const lastDotRegex = /\.([^.]+)$/;
|
|
6
|
-
const splitByLastDot = R.compose(R.init, R.split(lastDotRegex));
|
|
7
|
-
|
|
8
4
|
export function getNamespaceAndKey(namespacedKey: KeyName): KeyNameObj {
|
|
9
5
|
if (typeof namespacedKey !== "string") return namespacedKey;
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
if (!namespacedKey.includes(".")) {
|
|
8
|
+
return { namespace: DEFAULT_NAMESPACE, key: namespacedKey };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// split on the last dot - the namespace itself may contain dots
|
|
12
|
+
const lastDotIndex = namespacedKey.lastIndexOf(".");
|
|
14
13
|
|
|
15
|
-
return
|
|
14
|
+
return {
|
|
15
|
+
namespace: namespacedKey.slice(0, lastDotIndex),
|
|
16
|
+
key: namespacedKey.slice(lastDotIndex + 1),
|
|
17
|
+
};
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
+
const hasOwn = (obj: object, prop: string): boolean =>
|
|
21
|
+
Object.prototype.hasOwnProperty.call(obj, prop);
|
|
22
|
+
|
|
23
|
+
const isEmpty = (value: unknown): boolean => {
|
|
24
|
+
if (typeof value === "string" || Array.isArray(value)) {
|
|
25
|
+
return value.length === 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (value !== null && typeof value === "object") {
|
|
29
|
+
return Object.keys(value).length === 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return false;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const keyIsValid = (parsedKey: unknown): boolean => {
|
|
36
|
+
if (parsedKey == null) return false;
|
|
37
|
+
if (typeof parsedKey === "string") return false;
|
|
38
|
+
if (Array.isArray(parsedKey)) return false;
|
|
20
39
|
|
|
21
|
-
const
|
|
40
|
+
const obj = parsedKey as Record<string, unknown>;
|
|
22
41
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
propIsNotNullOrUndefined("key"),
|
|
30
|
-
propIsNotNullOrUndefined("namespace"),
|
|
31
|
-
propIsNotEmpty("key"),
|
|
32
|
-
propIsNotEmpty("namespace"),
|
|
33
|
-
]);
|
|
42
|
+
if (!hasOwn(obj, "key") || !hasOwn(obj, "namespace")) return false;
|
|
43
|
+
if (obj.key == null || obj.namespace == null) return false;
|
|
44
|
+
if (isEmpty(obj.key) || isEmpty(obj.namespace)) return false;
|
|
45
|
+
|
|
46
|
+
return true;
|
|
47
|
+
};
|
|
34
48
|
|
|
35
49
|
export const buildNamespaceKey = (key: string, namespace: string) =>
|
|
36
50
|
`${namespace}.${key}`;
|
|
37
51
|
|
|
38
|
-
export const savingResultIsSuccess = (result: unknown): boolean =>
|
|
39
|
-
|
|
40
|
-
};
|
|
52
|
+
export const savingResultIsSuccess = (result: unknown): boolean =>
|
|
53
|
+
typeof result === "boolean" && result === true;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { BehaviorSubject } from "rxjs";
|
|
2
2
|
|
|
3
3
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
4
|
+
import {
|
|
5
|
+
QUICK_BRICK_EVENTS,
|
|
6
|
+
sendQuickBrickEvent,
|
|
7
|
+
} from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
8
|
+
|
|
4
9
|
import {
|
|
5
10
|
isLgPlatform,
|
|
6
11
|
isSamsungPlatform,
|
|
@@ -18,6 +23,12 @@ const { log_debug } = createLogger({
|
|
|
18
23
|
parent: utilsLogger,
|
|
19
24
|
});
|
|
20
25
|
|
|
26
|
+
export const platformToBackground = () => {
|
|
27
|
+
sendQuickBrickEvent(QUICK_BRICK_EVENTS.MOVE_APP_TO_BACKGROUND, {
|
|
28
|
+
MOVE_APP_TO_BACKGROUND: true,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
21
32
|
export const getZappPlatform = (): ZappPlatform => {
|
|
22
33
|
const platform = appStore.get("appData")?.platform;
|
|
23
34
|
|