@applicaster/zapp-react-native-utils 12.0.0-alpha.5353184830 → 12.0.0-alpha.5400461972
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/ActionExecutorContext.tsx +16 -8
- package/analyticsUtils/AnalyticsEvents/index.ts +6 -0
- package/analyticsUtils/AnalyticsEvents/searchEvents.ts +21 -0
- package/analyticsUtils/__tests__/analyticsManager.test.js +75 -73
- package/analyticsUtils/analyticsPlugins.ts +25 -0
- package/analyticsUtils/events.ts +6 -0
- package/analyticsUtils/helpers/hooks.ts +1 -1
- package/analyticsUtils/index.tsx +6 -0
- package/appUtils/HooksManager/index.js +3 -1
- package/appUtils/focusManager/treeDataStructure/Utils/index.js +12 -3
- package/appUtils/keyCodes/__tests__/__snapshots__/keyCodes.test.js.snap +1 -1
- package/appUtils/keyCodes/__tests__/keyCodes.test.js +80 -85
- package/appUtils/keyCodes/keys.web.js +1 -0
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +53 -0
- package/appUtils/playerManager/conts.ts +5 -0
- package/appUtils/playerManager/player.ts +47 -4
- package/appUtils/playerManager/playerFactory.ts +15 -1
- package/appUtils/playerManager/playerNative.ts +35 -0
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +6 -1
- package/appUtils/playerManager/usePlayerState.tsx +13 -1
- package/appUtils/playerManager/usePlayerTitleSummaryOverlay.tsx +50 -0
- package/cellUtils/__tests__/cellUtils.test.ts +48 -0
- package/cellUtils/__tests__/fixtures.ts +13 -0
- package/cellUtils/index.ts +40 -2
- package/dateUtils/index.ts +11 -0
- package/focusManager/index.ts +1 -1
- package/functionUtils/__tests__/__snapshots__/functionUtils.test.js.snap +2 -2
- package/functionUtils/__tests__/functionUtils.test.js +244 -248
- package/headersUtils/index.ts +1 -0
- package/inflatedUrlUtils/index.ts +4 -4
- package/localizationUtils/__tests__/localizationUtils.test.ts +78 -55
- package/localizationUtils/index.ts +13 -19
- package/logger/index.ts +1 -1
- package/manifestUtils/defaultManifestConfigurations/generalContent.js +6 -0
- package/manifestUtils/defaultManifestConfigurations/player.js +10 -1
- package/manifestUtils/index.js +5 -1
- package/manifestUtils/secondaryImage/index.js +18 -15
- package/modalState/index.ts +57 -0
- package/navigationUtils/index.ts +56 -7
- package/numberUtils/index.ts +4 -0
- package/package.json +3 -2
- package/playerUtils/configurationGenerator.ts +11 -1
- package/pluginUtils/index.ts +11 -7
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +2 -0
- package/reactHooks/autoscrolling/__tests__/{useTrackedView.test.ts → useTrackedView.test.tsx} +18 -1
- package/reactHooks/cell-click/__tests__/index.test.js +11 -2
- package/reactHooks/cell-click/index.ts +4 -4
- package/reactHooks/feed/__tests__/useInflatedUrl.test.ts +18 -3
- package/reactHooks/feed/useInflatedUrl.ts +44 -15
- package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +16 -9
- package/reactHooks/index.ts +2 -0
- package/reactHooks/layout/__tests__/{index.test.js → index.test.tsx} +66 -59
- package/reactHooks/layout/getDeviceInfo/index.ts +4 -2
- package/reactHooks/layout/types/index.ts +2 -0
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.native.test.js +11 -16
- package/reactHooks/layout/useDimensions/helpers/__tests__/getInitialDimensions.test.js +12 -14
- package/reactHooks/layout/useDimensions/useDimensions.ts +13 -7
- package/reactHooks/navigation/__mocks__/index.ts +15 -0
- package/reactHooks/navigation/__mocks__/useNavigation.ts +7 -0
- package/reactHooks/navigation/__tests__/index.test.tsx +240 -81
- package/reactHooks/navigation/index.ts +204 -86
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +3 -1
- package/reactHooks/screen/__mocks__/useScreenContext.ts +3 -1
- package/reactHooks/screen/index.ts +2 -0
- package/reactHooks/screen/useScreenContext.ts +5 -4
- package/reactHooks/screen/useScreenData.ts +1 -1
- package/reactHooks/screen/useTargetScreenData.ts +7 -0
- package/reactHooks/state/useRivers.ts +3 -1
- package/reactHooks/useListenEventBusEvent.ts +1 -4
- package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +10 -9
- package/riverComponetsMeasurementProvider/index.tsx +2 -2
- package/stringUtils/index.ts +5 -0
- package/testUtils/getByTestId.ts +14 -0
- package/testUtils/index.tsx +38 -23
- package/types.ts +4 -0
|
@@ -11,11 +11,9 @@ import * as QuickBrickManager from "@applicaster/zapp-react-native-bridge/QuickB
|
|
|
11
11
|
import { showConfirmationDialog } from "../alertUtils";
|
|
12
12
|
import { createCloudEvent, sendCloudEvent } from "../cloudEventsUtils";
|
|
13
13
|
import { createLogger } from "../logger";
|
|
14
|
-
import {
|
|
15
|
-
StorageMultiSelectProvider
|
|
16
|
-
} from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
|
|
14
|
+
import { StorageMultiSelectProvider } from "@applicaster/zapp-react-native-bridge/ZappStorage/StorageMultiSelectProvider";
|
|
17
15
|
|
|
18
|
-
const { log_error,
|
|
16
|
+
const { log_error, log_info } = createLogger({
|
|
19
17
|
subsystem: "ActionExecutorContext",
|
|
20
18
|
category: "General",
|
|
21
19
|
});
|
|
@@ -110,11 +108,17 @@ const prepareDefaultActions = (actionExecutor) => {
|
|
|
110
108
|
const tag = entry?.extensions?.tag;
|
|
111
109
|
|
|
112
110
|
if (keyNamespace && tag) {
|
|
113
|
-
const multiSelectProvider =
|
|
111
|
+
const multiSelectProvider =
|
|
112
|
+
StorageMultiSelectProvider.getProvider(keyNamespace);
|
|
114
113
|
|
|
115
114
|
const selectedItems = await multiSelectProvider.getSelectedAsync();
|
|
116
115
|
const isTagInSelectedItems = selectedItems.includes(tag);
|
|
117
|
-
|
|
116
|
+
|
|
117
|
+
log_info(
|
|
118
|
+
`handleAction: localStorageToggleFlag event will ${
|
|
119
|
+
isTagInSelectedItems ? "remove" : "add"
|
|
120
|
+
} tag: ${tag} for keyNamespace: ${keyNamespace}, current selectedItems: ${selectedItems}`
|
|
121
|
+
);
|
|
118
122
|
|
|
119
123
|
if (selectedItems.includes(tag)) {
|
|
120
124
|
await multiSelectProvider.removeItem(tag);
|
|
@@ -122,13 +126,17 @@ const prepareDefaultActions = (actionExecutor) => {
|
|
|
122
126
|
await multiSelectProvider.addItem(tag);
|
|
123
127
|
}
|
|
124
128
|
} else {
|
|
125
|
-
log_error(
|
|
129
|
+
log_error(
|
|
130
|
+
"handleAction: localStorageToggleFlag event missing keyNamespace or tag",
|
|
131
|
+
{ keyNamespace, tag }
|
|
132
|
+
);
|
|
126
133
|
|
|
127
134
|
return ActionResult.Error;
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
return ActionResult.Success;
|
|
131
|
-
}
|
|
138
|
+
}
|
|
139
|
+
);
|
|
132
140
|
};
|
|
133
141
|
|
|
134
142
|
export const ActionExecutorContext =
|
|
@@ -7,6 +7,10 @@ import { sendHeaderClickEvent } from "./sendHeaderClickEvent";
|
|
|
7
7
|
import { sendHardwareBackButtonClickEvent } from "./sendHardwareBackButtonClickEvent";
|
|
8
8
|
import { sendDownloadsEvent } from "./sendDownloadsEvent";
|
|
9
9
|
import { sendScreenEvent } from "./sendScreenEvent";
|
|
10
|
+
import {
|
|
11
|
+
sendSearchCanceledEvent,
|
|
12
|
+
sendSearchExecutedEvent,
|
|
13
|
+
} from "./searchEvents";
|
|
10
14
|
|
|
11
15
|
export {
|
|
12
16
|
sendScreenEvent,
|
|
@@ -18,4 +22,6 @@ export {
|
|
|
18
22
|
sendHeaderClickEvent,
|
|
19
23
|
sendHardwareBackButtonClickEvent,
|
|
20
24
|
sendDownloadsEvent,
|
|
25
|
+
sendSearchCanceledEvent,
|
|
26
|
+
sendSearchExecutedEvent,
|
|
21
27
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { log_debug } from "../logger";
|
|
2
|
+
import { postAnalyticEvent } from "../manager";
|
|
3
|
+
import { ANALYTICS_CORE_EVENTS } from "../events";
|
|
4
|
+
|
|
5
|
+
export const sendSearchCanceledEvent = (analyticsProps) => {
|
|
6
|
+
const eventName = ANALYTICS_CORE_EVENTS.SEARCH_CANCELED;
|
|
7
|
+
postAnalyticEvent(eventName, analyticsProps);
|
|
8
|
+
|
|
9
|
+
log_debug(`sendSearchCanceledEvent: send event: ${eventName}`, {
|
|
10
|
+
analyticsProps,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const sendSearchExecutedEvent = (analyticsProps) => {
|
|
15
|
+
const eventName = ANALYTICS_CORE_EVENTS.SEARCH_EXECUTED;
|
|
16
|
+
postAnalyticEvent(eventName, analyticsProps);
|
|
17
|
+
|
|
18
|
+
log_debug(`sendSearchExecutedEvent: send event: ${eventName}`, {
|
|
19
|
+
analyticsProps,
|
|
20
|
+
});
|
|
21
|
+
};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
import * as ReactNative from "react-native";
|
|
2
|
+
|
|
1
3
|
const mock_postEvent = jest.fn();
|
|
2
4
|
const mock_setPlugins = jest.fn();
|
|
3
5
|
const mock_postTimedEvent = jest.fn();
|
|
4
6
|
const mock_endTimedEvent = jest.fn();
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
}));
|
|
8
|
+
const AnalyticsBridge = {
|
|
9
|
+
postEvent: mock_postEvent,
|
|
10
|
+
setPlugins: mock_setPlugins,
|
|
11
|
+
postTimedEvent: mock_postTimedEvent,
|
|
12
|
+
endTimedEvent: mock_endTimedEvent,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
ReactNative.NativeModules.AnalyticsBridge = AnalyticsBridge;
|
|
16
16
|
|
|
17
17
|
const eventName = "event";
|
|
18
18
|
const payload = {};
|
|
@@ -26,90 +26,92 @@ function clearAllMocks() {
|
|
|
26
26
|
mock_endTimedEvent.mockClear();
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
describe("
|
|
30
|
-
|
|
29
|
+
describe("AnalyticsManager", () => {
|
|
30
|
+
describe("isValidAnalyticsData", () => {
|
|
31
|
+
beforeEach(clearAllMocks);
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
it("returns false if eventName is not a string", () => {
|
|
34
|
+
expect(analyticsManager.isValidAnalyticsData(42)).toBe(false);
|
|
35
|
+
expect(analyticsManager.isValidAnalyticsData({})).toBe(false);
|
|
36
|
+
expect(analyticsManager.isValidAnalyticsData([])).toBe(false);
|
|
37
|
+
expect(analyticsManager.isValidAnalyticsData(() => ({}))).toBe(false);
|
|
38
|
+
});
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
it("returns false if payload is not an object", () => {
|
|
41
|
+
expect(analyticsManager.isValidAnalyticsData(eventName, "string")).toBe(
|
|
42
|
+
false
|
|
43
|
+
);
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
expect(analyticsManager.isValidAnalyticsData(eventName, 42)).toBe(false);
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
expect(analyticsManager.isValidAnalyticsData(eventName, () => ({}))).toBe(
|
|
48
|
+
false
|
|
49
|
+
);
|
|
50
|
+
});
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
it("returns true if eventName is a string and payload is null or an object", () => {
|
|
53
|
+
expect(analyticsManager.isValidAnalyticsData(eventName)).toBe(true);
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
expect(analyticsManager.isValidAnalyticsData(eventName, payload)).toBe(
|
|
56
|
+
true
|
|
57
|
+
);
|
|
58
|
+
});
|
|
57
59
|
});
|
|
58
|
-
});
|
|
59
60
|
|
|
60
|
-
describe("postAnalyticEvent", () => {
|
|
61
|
-
|
|
61
|
+
describe("postAnalyticEvent", () => {
|
|
62
|
+
beforeEach(clearAllMocks);
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
it("calls the postEvent method of the analytic bridge", () => {
|
|
65
|
+
analyticsManager.postAnalyticEvent(eventName, payload);
|
|
66
|
+
expect(mock_postEvent).toHaveBeenCalledWith(eventName, payload);
|
|
67
|
+
});
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
it("skips the event if it is not valid", () => {
|
|
70
|
+
analyticsManager.postAnalyticEvent(42);
|
|
71
|
+
expect(mock_postTimedEvent).not.toHaveBeenCalled();
|
|
72
|
+
});
|
|
71
73
|
});
|
|
72
|
-
});
|
|
73
74
|
|
|
74
|
-
describe("providePlugins", () => {
|
|
75
|
-
|
|
75
|
+
describe("providePlugins", () => {
|
|
76
|
+
beforeEach(clearAllMocks);
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
it("calls the setPlugins method of the analytic bridge", () => {
|
|
79
|
+
const plugins = [];
|
|
80
|
+
const plugin_configurations = {};
|
|
81
|
+
const callback = jest.fn();
|
|
81
82
|
|
|
82
|
-
|
|
83
|
+
analyticsManager.providePlugins(plugins, plugin_configurations, callback);
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
expect(mock_setPlugins).toHaveBeenCalledWith(
|
|
86
|
+
plugins,
|
|
87
|
+
plugin_configurations,
|
|
88
|
+
callback
|
|
89
|
+
);
|
|
90
|
+
});
|
|
89
91
|
});
|
|
90
|
-
});
|
|
91
92
|
|
|
92
|
-
describe("startAnalyticsTimedEvent", () => {
|
|
93
|
-
|
|
93
|
+
describe("startAnalyticsTimedEvent", () => {
|
|
94
|
+
beforeEach(clearAllMocks);
|
|
94
95
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
it("skips the event if it is not valid", () => {
|
|
97
|
+
analyticsManager.startAnalyticsTimedEvent(42);
|
|
98
|
+
expect(mock_postTimedEvent).not.toHaveBeenCalled();
|
|
99
|
+
});
|
|
98
100
|
});
|
|
99
|
-
});
|
|
100
101
|
|
|
101
|
-
describe("endAnalyticsTimedEvent", () => {
|
|
102
|
-
|
|
102
|
+
describe("endAnalyticsTimedEvent", () => {
|
|
103
|
+
beforeEach(clearAllMocks);
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
it("emits a time_on_screen event and adds duration to payload", () => {
|
|
106
|
+
analyticsManager.endAnalyticsTimedEvent(eventName, payload);
|
|
107
|
+
const newEventName = "time_on_screen";
|
|
108
|
+
payload.duration = "N/A";
|
|
109
|
+
expect(mock_postEvent).toHaveBeenCalledWith(newEventName, payload);
|
|
110
|
+
});
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
it("skips the event if it is not valid", () => {
|
|
113
|
+
analyticsManager.endAnalyticsTimedEvent(42);
|
|
114
|
+
expect(mock_postEvent).not.toHaveBeenCalled();
|
|
115
|
+
});
|
|
114
116
|
});
|
|
115
117
|
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as R from "ramda";
|
|
2
|
+
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
3
|
+
|
|
4
|
+
export const getVideojsAnalyticPluginsConfig = async (entry: ZappEntry) => {
|
|
5
|
+
let videojsConfiguration = {};
|
|
6
|
+
|
|
7
|
+
const plugins = appStore.get("plugins");
|
|
8
|
+
const analyticPlugins = R.filter(R.propEq("type", "analytics"), plugins);
|
|
9
|
+
|
|
10
|
+
const configurations = await Promise.all(
|
|
11
|
+
analyticPlugins.map(async (plugin) => {
|
|
12
|
+
const { configuration, module } = plugin;
|
|
13
|
+
|
|
14
|
+
return module?.getPlayerConfiguration?.(configuration, entry);
|
|
15
|
+
})
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
configurations.forEach((analyticConfig) => {
|
|
19
|
+
if (typeof analyticConfig === "object" && analyticConfig !== null) {
|
|
20
|
+
videojsConfiguration = { ...videojsConfiguration, ...analyticConfig };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return videojsConfiguration;
|
|
25
|
+
};
|
package/analyticsUtils/events.ts
CHANGED
|
@@ -23,10 +23,16 @@ export const TAPPING_EVENTS = {
|
|
|
23
23
|
TAP_NAVBAR_BACK_BUTTON: "tap_navbar_back_button",
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
export const SEARCH_EVENTS = {
|
|
27
|
+
SEARCH_EXECUTED: "search_executed",
|
|
28
|
+
SEARCH_CANCELED: "search_canceled",
|
|
29
|
+
};
|
|
30
|
+
|
|
26
31
|
export const ANALYTICS_CORE_EVENTS = {
|
|
27
32
|
...LEGACY_EVENTS,
|
|
28
33
|
...SCREEN_VIEW_EVENTS,
|
|
29
34
|
...TAPPING_EVENTS,
|
|
35
|
+
...SEARCH_EVENTS,
|
|
30
36
|
};
|
|
31
37
|
|
|
32
38
|
export const WEBVIEW_EVENTS = {
|
|
@@ -26,7 +26,7 @@ export const useHookAnalytics = (props): void => {
|
|
|
26
26
|
if (screenData?.hookPlugin?.module?.runInBackground) {
|
|
27
27
|
sendScreenEvent({ analyticsScreenData });
|
|
28
28
|
}
|
|
29
|
-
}, [hookPlugin.screen_id]);
|
|
29
|
+
}, [sendScreenEvent, screenData, hookPlugin.screen_id]);
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
export const useScreenAnalytics = (props) => {
|
package/analyticsUtils/index.tsx
CHANGED
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
sendHardwareBackButtonClickEvent,
|
|
19
19
|
sendDownloadsEvent,
|
|
20
20
|
sendScreenEvent,
|
|
21
|
+
sendSearchCanceledEvent,
|
|
22
|
+
sendSearchExecutedEvent,
|
|
21
23
|
} from "./AnalyticsEvents";
|
|
22
24
|
|
|
23
25
|
import { postAnalyticEvent } from "./manager";
|
|
@@ -66,6 +68,8 @@ type AnalyticsFunctions = {
|
|
|
66
68
|
item: ZappEntry;
|
|
67
69
|
state: OfflineItemState;
|
|
68
70
|
}) => void;
|
|
71
|
+
sendSearchCanceledEvent: (props: AnalyticsDefaultProperties) => void;
|
|
72
|
+
sendSearchExecutedEvent: (props: AnalyticsDefaultProperties) => void;
|
|
69
73
|
};
|
|
70
74
|
|
|
71
75
|
type GetAnalyticsFunctions = (
|
|
@@ -102,6 +106,8 @@ export function getAnalyticsFunctions({
|
|
|
102
106
|
sendHardwareBackButtonClickEvent,
|
|
103
107
|
sendScreenEvent,
|
|
104
108
|
sendDownloadsEvent,
|
|
109
|
+
sendSearchCanceledEvent,
|
|
110
|
+
sendSearchExecutedEvent,
|
|
105
111
|
};
|
|
106
112
|
}
|
|
107
113
|
|
|
@@ -270,7 +270,9 @@ export function HooksManager({
|
|
|
270
270
|
});
|
|
271
271
|
|
|
272
272
|
const isHookInHomescreen = payload?.home;
|
|
273
|
-
|
|
273
|
+
|
|
274
|
+
const isHookFlowBlocker =
|
|
275
|
+
hookPlugin?.module?.isFlowBlocker?.() ?? false;
|
|
274
276
|
|
|
275
277
|
// TODO: We technically need to also support the case where there is more than one hook in the stack,
|
|
276
278
|
// if needed we could add differentiation explicit user cancellation (when we should go to background) and other types of cancellation
|
|
@@ -187,11 +187,20 @@ export function getTargetInDirection(
|
|
|
187
187
|
return null;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
const orientationDistance = measureDistance(
|
|
191
|
+
direction,
|
|
192
|
+
comparisonRect,
|
|
193
|
+
componentRect
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const euclidDistance = measureEuclidianDistanceToCenter(
|
|
197
|
+
comparisonRect,
|
|
198
|
+
componentRect
|
|
199
|
+
);
|
|
200
|
+
|
|
190
201
|
return {
|
|
191
202
|
distance:
|
|
192
|
-
|
|
193
|
-
measureEuclidianDistanceToCenter(comparisonRect, componentRect) /
|
|
194
|
-
10000,
|
|
203
|
+
orientationDistance > 0 ? euclidDistance : orientationDistance,
|
|
195
204
|
target,
|
|
196
205
|
};
|
|
197
206
|
})
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
const { Platform } = require("react-native");
|
|
2
|
+
|
|
3
|
+
Platform.OS = "web";
|
|
4
|
+
|
|
1
5
|
import { directionHelper } from "../../directionHelper";
|
|
2
6
|
|
|
3
7
|
const globalTizen = {
|
|
@@ -6,105 +10,96 @@ const globalTizen = {
|
|
|
6
10
|
},
|
|
7
11
|
};
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe("keyCode", () => {
|
|
14
|
-
const { keyCode } = require("../index");
|
|
15
|
-
const { KEYS } = require("../keys.web");
|
|
16
|
-
|
|
17
|
-
it("returns an object for a given key event", () => {
|
|
18
|
-
expect(keyCode(KEYS.Enter)).toMatchSnapshot();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("has a matcher method for a single key", () => {
|
|
22
|
-
expect(keyCode(KEYS.Enter).matches("Enter")).toBeTruthy();
|
|
23
|
-
expect(keyCode(KEYS.Enter).matches(KEYS.Enter)).toBeTruthy();
|
|
24
|
-
expect(keyCode(KEYS.Back).matches("Enter")).toBeFalsy();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("has matcher for multiple keys", () => {
|
|
28
|
-
expect(
|
|
29
|
-
keyCode(KEYS.Enter).matchesAny("Enter", "Back", "ArrowUp")
|
|
30
|
-
).toBeTruthy();
|
|
13
|
+
describe("keyCodes", () => {
|
|
14
|
+
describe("keyCode", () => {
|
|
15
|
+
const { keyCode } = require("..");
|
|
16
|
+
const { KEYS } = require("../keys.web");
|
|
31
17
|
|
|
32
|
-
|
|
33
|
-
keyCode(KEYS.Enter).
|
|
34
|
-
)
|
|
35
|
-
});
|
|
18
|
+
it("returns an object for a given key event", () => {
|
|
19
|
+
expect(keyCode(KEYS.Enter)).toMatchSnapshot();
|
|
20
|
+
});
|
|
36
21
|
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
it("has a matcher method for a single key", () => {
|
|
23
|
+
expect(keyCode(KEYS.Enter).matches("Enter")).toBeTruthy();
|
|
24
|
+
expect(keyCode(KEYS.Enter).matches(KEYS.Enter)).toBeTruthy();
|
|
25
|
+
expect(keyCode(KEYS.Back).matches("Enter")).toBeFalsy();
|
|
26
|
+
});
|
|
39
27
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
28
|
+
it("has matcher for multiple keys", () => {
|
|
29
|
+
expect(
|
|
30
|
+
keyCode(KEYS.Enter).matchesAny("Enter", "Back", "ArrowUp")
|
|
31
|
+
).toBeTruthy();
|
|
44
32
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
expect(
|
|
34
|
+
keyCode(KEYS.Enter).matchesAny("Back", "ArrowUp", "ArrowDown")
|
|
35
|
+
).toBeFalsy();
|
|
48
36
|
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
37
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return { Platform: { OS: "samsung_tv" } };
|
|
55
|
-
});
|
|
38
|
+
it("returns the direction if it matches an arrow key", () => {
|
|
39
|
+
expect(keyCode(KEYS.Enter).direction()).toBe(null);
|
|
56
40
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
41
|
+
expect(keyCode(KEYS.ArrowDown).direction()).toEqual(
|
|
42
|
+
directionHelper(KEYS.ArrowDown)
|
|
43
|
+
);
|
|
44
|
+
});
|
|
61
45
|
|
|
62
|
-
|
|
63
|
-
|
|
46
|
+
describe("in web env", () => {
|
|
47
|
+
it("uses the proper keyCode for the environment", () => {
|
|
48
|
+
expect(keyCode({ keyCode: 13 }).matches(KEYS.Enter)).toBeTruthy();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
64
51
|
});
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
53
|
+
describe("in Tizen Env", () => {
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
jest.resetModules();
|
|
56
|
+
global.tizen = globalTizen;
|
|
57
|
+
});
|
|
69
58
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"MediaPlayPause",
|
|
74
|
-
"MediaPause",
|
|
75
|
-
"MediaFastForward",
|
|
76
|
-
"MediaRewind",
|
|
77
|
-
"MediaStop",
|
|
78
|
-
"Exit",
|
|
79
|
-
"0",
|
|
80
|
-
"1",
|
|
81
|
-
"2",
|
|
82
|
-
"3",
|
|
83
|
-
"4",
|
|
84
|
-
"5",
|
|
85
|
-
"6",
|
|
86
|
-
"7",
|
|
87
|
-
"8",
|
|
88
|
-
"9",
|
|
89
|
-
]);
|
|
90
|
-
|
|
91
|
-
expect(keyCode({ keyCode: 10009 }).matches(KEYS.Back)).toBeTruthy();
|
|
92
|
-
});
|
|
93
|
-
});
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
global.tizen = undefined;
|
|
61
|
+
});
|
|
94
62
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
63
|
+
it("uses the proper keyCode for the environment", () => {
|
|
64
|
+
Platform.OS = "samsung_tv";
|
|
65
|
+
const { keyCode } = require("../");
|
|
66
|
+
const { KEYS } = require("../keys.web");
|
|
67
|
+
|
|
68
|
+
expect(globalTizen.tvinputdevice.registerKeyBatch).toHaveBeenCalledWith([
|
|
69
|
+
"MediaPlay",
|
|
70
|
+
"MediaPlayPause",
|
|
71
|
+
"MediaPause",
|
|
72
|
+
"MediaFastForward",
|
|
73
|
+
"MediaRewind",
|
|
74
|
+
"MediaStop",
|
|
75
|
+
"Exit",
|
|
76
|
+
"0",
|
|
77
|
+
"1",
|
|
78
|
+
"2",
|
|
79
|
+
"3",
|
|
80
|
+
"4",
|
|
81
|
+
"5",
|
|
82
|
+
"6",
|
|
83
|
+
"7",
|
|
84
|
+
"8",
|
|
85
|
+
"9",
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
expect(keyCode({ keyCode: 10009 }).matches(KEYS.Back)).toBeTruthy();
|
|
89
|
+
});
|
|
98
90
|
});
|
|
99
91
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
92
|
+
describe("in WebOS Env", () => {
|
|
93
|
+
beforeEach(() => {
|
|
94
|
+
jest.resetModules();
|
|
95
|
+
});
|
|
103
96
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
it("uses the proper keyCode for the environment", () => {
|
|
98
|
+
Platform.OS = "lg_tv";
|
|
99
|
+
const { keyCode } = require("..");
|
|
100
|
+
const { KEYS } = require("../keys.web");
|
|
101
|
+
// Back is reserved on LG
|
|
102
|
+
expect(keyCode({ keyCode: 417 }).matches(KEYS.Forward)).toBeTruthy();
|
|
103
|
+
});
|
|
109
104
|
});
|
|
110
105
|
});
|