@applicaster/zapp-react-native-ui-components 12.0.0-alpha.5882013252 → 12.0.0-alpha.6437417031

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/Components/AnimatedInOut/index.tsx +18 -10
  2. package/Components/AudioPlayer/AudioPlayer.tsx +9 -1
  3. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +5 -0
  4. package/Components/AudioPlayer/helpers.tsx +1 -0
  5. package/Components/Cell/Cell.tsx +2 -2
  6. package/Components/Cell/CellWithFocusable.tsx +21 -14
  7. package/Components/Cell/TvOSCellComponent.tsx +2 -2
  8. package/Components/ErrorScreen/index.tsx +1 -1
  9. package/Components/FocusableCell/index.tsx +7 -7
  10. package/Components/FocusableList/FocusableChild.ts +24 -14
  11. package/Components/FocusableList/FocusableItem.tsx +1 -1
  12. package/Components/FocusableList/FocusableListItemWrapper.tsx +76 -0
  13. package/Components/FocusableList/hooks/useCellState.android.ts +3 -1
  14. package/Components/FocusableList/index.tsx +26 -25
  15. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +11 -8
  16. package/Components/HandlePlayable/HandlePlayable.tsx +1 -1
  17. package/Components/HookRenderer/index.tsx +1 -6
  18. package/Components/Image/Image.android.tsx +3 -22
  19. package/Components/Image/Image.tsx +18 -2
  20. package/Components/Image/utils/index.ts +39 -0
  21. package/Components/Layout/TV/__tests__/index.test.tsx +1 -34
  22. package/Components/Layout/TV/index.tsx +20 -36
  23. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +0 -1
  24. package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +21 -8
  25. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +9 -26
  26. package/Components/MasterCell/DefaultComponents/Image/hooks/useImageSize.ts +65 -0
  27. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +3 -1
  28. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +3 -2
  29. package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
  30. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +8 -10
  31. package/Components/ModalComponent/BottomSheetModalContent.tsx +121 -0
  32. package/Components/ModalComponent/Button/Item.tsx +82 -0
  33. package/Components/ModalComponent/Button/ItemIcon.tsx +60 -0
  34. package/Components/ModalComponent/Button/ItemLabel.tsx +101 -0
  35. package/Components/ModalComponent/Button/assets.ts +4 -0
  36. package/Components/ModalComponent/Button/index.tsx +111 -0
  37. package/Components/ModalComponent/Header/CloseButton.tsx +59 -0
  38. package/Components/ModalComponent/Header/Title.tsx +70 -0
  39. package/Components/ModalComponent/Header/assets.ts +4 -0
  40. package/Components/ModalComponent/Header/index.tsx +71 -0
  41. package/Components/ModalComponent/Header/utils.ts +79 -0
  42. package/Components/ModalComponent/index.tsx +38 -0
  43. package/Components/ModalComponent/utils.ts +126 -0
  44. package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +4 -7
  45. package/Components/PlayerContainer/PlayerContainer.tsx +52 -28
  46. package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -1
  47. package/Components/River/ComponentsMap/ComponentsMap.tsx +25 -0
  48. package/Components/River/River.tsx +8 -5
  49. package/Components/River/TV/River.tsx +2 -2
  50. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +1 -1
  51. package/Components/River/__tests__/componentsMap.test.js +1 -0
  52. package/Components/River/useScreenConfiguration.ts +5 -6
  53. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +1 -0
  54. package/Components/RouteManager/__tests__/routeManager.test.js +9 -2
  55. package/Components/RouteManager/index.tsx +5 -3
  56. package/Components/Screen/__tests__/Screen.test.tsx +48 -36
  57. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +20 -6
  58. package/Components/Screen/__tests__/navigationHandler.test.ts +1 -178
  59. package/Components/Screen/index.tsx +91 -43
  60. package/Components/Screen/navigationHandler.ts +0 -82
  61. package/Components/Screen/orientationHandler.ts +1 -1
  62. package/Components/ScreenResolver/index.tsx +1 -1
  63. package/Components/Tabs/TV/styles.ts +1 -1
  64. package/Components/TrackedView/index.tsx +6 -3
  65. package/Components/VideoLive/LiveImageManager.ts +42 -13
  66. package/Components/VideoLive/PlayerLiveImageComponent.tsx +81 -72
  67. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +30 -3
  68. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +22 -27
  69. package/Components/VideoModal/PlayerDetails.tsx +3 -0
  70. package/Components/VideoModal/PlayerWrapper.tsx +66 -65
  71. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +0 -2
  72. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +4 -4
  73. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +206 -162
  74. package/Components/VideoModal/hooks/useModalSize.ts +13 -4
  75. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +26 -21
  76. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +4 -5
  77. package/Components/ZappUIComponent/index.tsx +22 -12
  78. package/Components/index.js +2 -0
  79. package/Contexts/ScreenContext/index.tsx +1 -4
  80. package/Decorators/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
  81. package/Decorators/RiverResolver/index.tsx +0 -4
  82. package/Decorators/index.tsx +0 -4
  83. package/package.json +5 -6
@@ -19,8 +19,6 @@ const props = {
19
19
 
20
20
  const useIsTablet = jest.fn();
21
21
 
22
- jest.mock("react-native");
23
-
24
22
  jest.mock("../PlayerDetails", () => ({ PlayerDetails: View }));
25
23
 
26
24
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks/device", () => ({
@@ -38,6 +36,7 @@ jest.mock("@applicaster/zapp-react-native-utils/reactUtils", () => ({
38
36
  }));
39
37
 
40
38
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
39
+ isNavBarVisible: jest.fn(() => true),
41
40
  useRoute: jest.fn(() => ({
42
41
  pathname: "/river/testId",
43
42
  })),
@@ -50,7 +49,7 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
50
49
 
51
50
  jest.mock("../utils", () => ({ playerDimesionsHack: {} }));
52
51
 
53
- const { PlayerWrapper, defaultAspectRatioWidth } = require("../PlayerWrapper");
52
+ const { PlayerWrapper } = require("../PlayerWrapper");
54
53
 
55
54
  jest.useFakeTimers();
56
55
  const children = jest.fn(() => {});
@@ -110,7 +109,8 @@ describe("PlayerWrapper", () => {
110
109
 
111
110
  const expectDimensions = {
112
111
  ...dimensions,
113
- width: defaultAspectRatioWidth(dimensions.height),
112
+ width: undefined,
113
+ aspectRatio: 16 / 9,
114
114
  };
115
115
 
116
116
  expect(element).toMatchSnapshot();
@@ -1,253 +1,297 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`PlayerWrapper renders inline 1`] = `
4
- <RNCSafeAreaView
5
- edges={
6
- Object {
7
- "bottom": "off",
8
- "left": "off",
9
- "right": "off",
10
- "top": "additive",
11
- }
12
- }
4
+ <RNCSafeAreaProvider
5
+ onInsetsChange={[Function]}
13
6
  style={
14
7
  Array [
15
8
  Object {
16
- "flexDirection": "column",
17
- },
18
- Object {
19
- "backgroundColor": "transparent",
20
- },
21
- Object {
22
- "height": 800,
23
- "width": 300,
9
+ "flex": 1,
24
10
  },
25
- Object {},
11
+ undefined,
26
12
  ]
27
13
  }
28
14
  >
29
- <View
15
+ <RNCSafeAreaView
16
+ edges={
17
+ Object {
18
+ "bottom": "off",
19
+ "left": "off",
20
+ "right": "off",
21
+ "top": "additive",
22
+ }
23
+ }
30
24
  style={
31
25
  Array [
32
26
  Object {
33
- "alignSelf": "center",
34
- "position": "relative",
35
- "zIndex": 200,
27
+ "flexDirection": "column",
36
28
  },
37
29
  Object {
38
- "height": 421.875,
39
- "width": 300,
30
+ "backgroundColor": "transparent",
40
31
  },
41
- Object {},
42
32
  Object {
43
- "aspectRatio": 1.7777777777777777,
44
- "height": undefined,
45
- "width": "100%",
33
+ "height": 800,
34
+ "width": 300,
46
35
  },
47
36
  Object {},
48
37
  ]
49
38
  }
50
- testID="test-player-container"
51
- />
52
- <View
53
- configuration={
54
- Object {
55
- "tablet_landscape_player_container_background_color": "red",
56
- "tablet_landscape_sidebar_width": "35%",
39
+ >
40
+ <View
41
+ style={
42
+ Array [
43
+ Object {
44
+ "alignSelf": "center",
45
+ "position": "relative",
46
+ "zIndex": 200,
47
+ },
48
+ Object {
49
+ "aspectRatio": 1.7777777777777777,
50
+ "height": undefined,
51
+ "width": "100%",
52
+ },
53
+ Object {},
54
+ Object {},
55
+ ]
57
56
  }
58
- }
59
- entry={
60
- Object {
61
- "id": "test",
57
+ testID="test-player-container"
58
+ />
59
+ <View
60
+ configuration={
61
+ Object {
62
+ "tablet_landscape_player_container_background_color": "red",
63
+ "tablet_landscape_sidebar_width": "35%",
64
+ }
62
65
  }
63
- }
64
- isTabletLandscape={false}
65
- style={
66
- Object {
67
- "flex": 1,
68
- "paddingTop": 20,
66
+ entry={
67
+ Object {
68
+ "id": "test",
69
+ }
69
70
  }
70
- }
71
- />
72
- </RNCSafeAreaView>
71
+ isTabletLandscape={false}
72
+ style={
73
+ Object {
74
+ "flex": 1,
75
+ "paddingTop": 20,
76
+ }
77
+ }
78
+ />
79
+ </RNCSafeAreaView>
80
+ </RNCSafeAreaProvider>
73
81
  `;
74
82
 
75
83
  exports[`PlayerWrapper renders inline and docked 1`] = `
76
- <RNCSafeAreaView
77
- edges={
78
- Object {
79
- "bottom": "additive",
80
- "left": "off",
81
- "right": "off",
82
- "top": "off",
83
- }
84
- }
84
+ <RNCSafeAreaProvider
85
+ onInsetsChange={[Function]}
85
86
  style={
86
87
  Array [
87
88
  Object {
88
- "flexDirection": "column",
89
- },
90
- Object {
91
- "backgroundColor": "transparent",
92
- },
93
- Object {
94
- "height": 50,
95
- "width": 300,
89
+ "flex": 1,
96
90
  },
97
- Object {},
91
+ undefined,
98
92
  ]
99
93
  }
100
94
  >
101
- <View
95
+ <RNCSafeAreaView
96
+ edges={
97
+ Object {
98
+ "bottom": "additive",
99
+ "left": "off",
100
+ "right": "off",
101
+ "top": "off",
102
+ }
103
+ }
102
104
  style={
103
105
  Array [
104
106
  Object {
105
- "alignSelf": "center",
106
- "position": "relative",
107
- "zIndex": 200,
107
+ "flexDirection": "column",
108
+ },
109
+ Object {
110
+ "backgroundColor": "transparent",
108
111
  },
109
112
  Object {
110
113
  "height": 50,
111
114
  "width": 300,
112
115
  },
113
116
  Object {},
114
- Object {},
115
- Object {},
116
117
  ]
117
118
  }
118
- testID="test-player-container"
119
- />
120
- <View
121
- style={
122
- Object {
123
- "flex": 1,
124
- "paddingTop": 20,
119
+ >
120
+ <View
121
+ style={
122
+ Array [
123
+ Object {
124
+ "alignSelf": "center",
125
+ "position": "relative",
126
+ "zIndex": 200,
127
+ },
128
+ Object {
129
+ "aspectRatio": undefined,
130
+ "height": 50,
131
+ "width": "100%",
132
+ },
133
+ Object {},
134
+ Object {},
135
+ ]
125
136
  }
126
- }
127
- />
128
- </RNCSafeAreaView>
137
+ testID="test-player-container"
138
+ />
139
+ <View
140
+ style={
141
+ Object {
142
+ "flex": 1,
143
+ "paddingTop": 20,
144
+ }
145
+ }
146
+ />
147
+ </RNCSafeAreaView>
148
+ </RNCSafeAreaProvider>
129
149
  `;
130
150
 
131
151
  exports[`PlayerWrapper renders inline on tablet in landscape orientation 1`] = `
132
- <RNCSafeAreaView
133
- edges={
134
- Object {
135
- "bottom": "off",
136
- "left": "off",
137
- "right": "off",
138
- "top": "additive",
139
- }
140
- }
152
+ <RNCSafeAreaProvider
153
+ onInsetsChange={[Function]}
141
154
  style={
142
155
  Array [
143
156
  Object {
144
- "flexDirection": "row",
145
- },
146
- Object {
147
- "backgroundColor": "red",
148
- },
149
- Object {
150
- "height": 800,
151
- "width": 300,
157
+ "flex": 1,
152
158
  },
153
- Object {},
159
+ undefined,
154
160
  ]
155
161
  }
156
162
  >
157
- <View
163
+ <RNCSafeAreaView
164
+ edges={
165
+ Object {
166
+ "bottom": "off",
167
+ "left": "off",
168
+ "right": "off",
169
+ "top": "additive",
170
+ }
171
+ }
158
172
  style={
159
173
  Array [
160
174
  Object {
161
- "alignSelf": "center",
162
- "position": "relative",
163
- "zIndex": 200,
175
+ "flexDirection": "row",
164
176
  },
165
177
  Object {
166
- "height": 109.6875,
167
- "width": 195,
178
+ "backgroundColor": "red",
179
+ },
180
+ Object {
181
+ "height": 800,
182
+ "width": 300,
168
183
  },
169
- Object {},
170
- Object {},
171
184
  Object {},
172
185
  ]
173
186
  }
174
- testID="test-player-container"
175
- />
176
- <View
177
- configuration={
178
- Object {
179
- "tablet_landscape_player_container_background_color": "red",
180
- "tablet_landscape_sidebar_width": "35%",
187
+ >
188
+ <View
189
+ style={
190
+ Array [
191
+ Object {
192
+ "alignSelf": "center",
193
+ "position": "relative",
194
+ "zIndex": 200,
195
+ },
196
+ Object {
197
+ "aspectRatio": 1.7777777777777777,
198
+ "height": undefined,
199
+ "width": 195,
200
+ },
201
+ Object {},
202
+ Object {},
203
+ ]
181
204
  }
182
- }
183
- entry={
184
- Object {
185
- "id": "test",
205
+ testID="test-player-container"
206
+ />
207
+ <View
208
+ configuration={
209
+ Object {
210
+ "tablet_landscape_player_container_background_color": "red",
211
+ "tablet_landscape_sidebar_width": "35%",
212
+ }
186
213
  }
187
- }
188
- isTabletLandscape={true}
189
- style={
190
- Object {
191
- "flex": 1,
192
- "paddingTop": 20,
214
+ entry={
215
+ Object {
216
+ "id": "test",
217
+ }
193
218
  }
194
- }
195
- />
196
- </RNCSafeAreaView>
219
+ isTabletLandscape={true}
220
+ style={
221
+ Object {
222
+ "flex": 1,
223
+ "paddingTop": 20,
224
+ }
225
+ }
226
+ />
227
+ </RNCSafeAreaView>
228
+ </RNCSafeAreaProvider>
197
229
  `;
198
230
 
199
231
  exports[`PlayerWrapper renders properly 1`] = `
200
- <RNCSafeAreaView
201
- edges={
202
- Object {
203
- "bottom": "off",
204
- "left": "off",
205
- "right": "off",
206
- "top": "additive",
207
- }
208
- }
232
+ <RNCSafeAreaProvider
233
+ onInsetsChange={[Function]}
209
234
  style={
210
235
  Array [
211
236
  Object {
212
- "flexDirection": "column",
213
- },
214
- Object {
215
- "backgroundColor": "transparent",
216
- },
217
- Object {
218
- "height": 800,
219
- "width": 300,
237
+ "flex": 1,
220
238
  },
221
- Object {},
239
+ undefined,
222
240
  ]
223
241
  }
224
242
  >
225
- <View
243
+ <RNCSafeAreaView
244
+ edges={
245
+ Object {
246
+ "bottom": "off",
247
+ "left": "off",
248
+ "right": "off",
249
+ "top": "additive",
250
+ }
251
+ }
226
252
  style={
227
253
  Array [
228
254
  Object {
229
- "alignSelf": "center",
230
- "position": "relative",
231
- "zIndex": 200,
255
+ "flexDirection": "column",
256
+ },
257
+ Object {
258
+ "backgroundColor": "transparent",
232
259
  },
233
260
  Object {
234
261
  "height": 800,
235
262
  "width": 300,
236
263
  },
237
264
  Object {},
238
- Object {},
239
- Object {},
240
265
  ]
241
266
  }
242
- testID="test-player-container"
243
- />
244
- <View
245
- style={
246
- Object {
247
- "flex": 1,
248
- "paddingTop": 20,
267
+ >
268
+ <View
269
+ style={
270
+ Array [
271
+ Object {
272
+ "alignSelf": "center",
273
+ "position": "relative",
274
+ "zIndex": 200,
275
+ },
276
+ Object {
277
+ "aspectRatio": 1.7786666666666666,
278
+ "height": undefined,
279
+ "width": "100%",
280
+ },
281
+ Object {},
282
+ Object {},
283
+ ]
249
284
  }
250
- }
251
- />
252
- </RNCSafeAreaView>
285
+ testID="test-player-container"
286
+ />
287
+ <View
288
+ style={
289
+ Object {
290
+ "flex": 1,
291
+ "paddingTop": 20,
292
+ }
293
+ }
294
+ />
295
+ </RNCSafeAreaView>
296
+ </RNCSafeAreaProvider>
253
297
  `;
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import * as React from "react";
2
2
  import { Dimensions } from "react-native";
3
3
  import { useIsTabletLandscape } from "@applicaster/zapp-react-native-utils/reactHooks/device/useMemoizedIsTablet";
4
4
  import {
@@ -39,13 +39,22 @@ export const useModalSize = (): Size => {
39
39
  MODAL_SIZE_FOR_PORTRAIT
40
40
  );
41
41
 
42
- const setNewModalSize = (size, log) => {
43
- setModalSize(size);
42
+ const setNewModalSize = React.useCallback((newSize, log) => {
43
+ setModalSize((oldSize) => {
44
+ if (
45
+ oldSize.height === newSize.height &&
46
+ oldSize.width === newSize.width
47
+ ) {
48
+ return oldSize;
49
+ }
50
+
51
+ return newSize;
52
+ });
44
53
 
45
54
  logger.debug({
46
55
  message: log,
47
56
  });
48
- };
57
+ }, []);
49
58
 
50
59
  const isTabletLandscape = useIsTabletLandscape();
51
60
 
@@ -1,35 +1,38 @@
1
1
  /* eslint-disable react/prop-types */
2
2
 
3
- jest.mock("react-native", () => {
4
- const { ScrollView } = jest.requireActual("react-native");
3
+ import * as React from "react";
4
+
5
+ import { shallow } from "enzyme";
6
+ import { create, act } from "react-test-renderer";
7
+ import { shallowToJson } from "enzyme-to-json";
8
+
9
+ import { ViewportEvents } from "../../ViewportEvents";
10
+
11
+ jest.useFakeTimers();
5
12
 
13
+ jest.mock("react-native/Libraries/ReactNative/UIManager", () => {
6
14
  return {
7
- ScrollView,
8
- UIManager: {
9
- measureLayout: jest.fn((handle, parent, error, success) => {
10
- success(100, 100, 400, 400);
11
- }),
12
- },
13
- findNodeHandle: jest.fn(() => 1234),
14
- Animated: {
15
- timing: jest.fn(() => ({ start: jest.fn() })),
15
+ ...jest.requireActual("react-native/Libraries/ReactNative/NativeUIManager"),
16
+ measureLayout: (handle, parent, error, success) => {
17
+ success(100, 100, 400, 400);
16
18
  },
17
19
  };
18
20
  });
19
21
 
20
- import * as React from "react";
22
+ jest.mock("react-native/Libraries/Renderer/shims/ReactNative", () => ({
23
+ ...jest.requireActual("react-native/Libraries/Renderer/shims/ReactNative"),
24
+ findNodeHandle: () => 1234,
25
+ }));
21
26
 
22
- import { shallow } from "enzyme";
23
- import TestRenderer from "react-test-renderer";
24
- import { act } from "@testing-library/react-hooks";
25
- import { shallowToJson } from "enzyme-to-json";
27
+ const ReactNative = require("react-native");
26
28
 
27
- import { ViewportEvents } from "../../ViewportEvents";
29
+ const { Animated, ScrollView } = ReactNative;
30
+
31
+ Animated.timing = jest.fn(() => ({ start: jest.fn() }));
28
32
 
29
33
  const viewportEventsManager = new ViewportEvents(true);
30
34
 
31
- const { ScrollView } = require("react-native");
32
- const { ViewportAware } = require("../index");
35
+ const { ViewportAware } = require("../");
33
36
  const { ViewportTracker } = require("../../ViewportTracker");
34
37
 
35
38
  const TestComponent = (props) => {
@@ -116,7 +119,7 @@ describe("<ViewportAware />", () => {
116
119
  });
117
120
 
118
121
  it("invokes the onViewportEnter function when entering the viewport", () => {
119
- const wrapper = TestRenderer.create(
122
+ const wrapper = create(
120
123
  getWrapper(() => (
121
124
  <TestComponent
122
125
  preTriggerRatio={0.1}
@@ -134,6 +137,8 @@ describe("<ViewportAware />", () => {
134
137
  width: 1920,
135
138
  height: 1080,
136
139
  });
140
+
141
+ jest.runAllTimers();
137
142
  });
138
143
 
139
144
  expect(wrapper.toJSON()).toMatchSnapshot();
@@ -151,7 +156,7 @@ describe("<ViewportAware />", () => {
151
156
  });
152
157
 
153
158
  it("invokes the onViewportLeave function when leaving the viewport", () => {
154
- const wrapper = TestRenderer.create(
159
+ const wrapper = create(
155
160
  getWrapper(() => (
156
161
  <TestComponent
157
162
  preTriggerRatio={0.1}
@@ -5,11 +5,10 @@ import { ViewportEvents } from "../../ViewportEvents";
5
5
 
6
6
  const TestComponent = () => <ScrollView />;
7
7
 
8
- jest.mock("react-native", () => {
9
- return {
10
- findNodeHandle: jest.fn(() => 1234),
11
- };
12
- });
8
+ jest.mock("react-native/Libraries/Renderer/shims/ReactNative", () => ({
9
+ ...jest.requireActual("react-native/Libraries/Renderer/shims/ReactNative"),
10
+ findNodeHandle: () => 1234,
11
+ }));
13
12
 
14
13
  const viewportEventsManager = new ViewportEvents(true);
15
14