@applicaster/zapp-react-native-ui-components 13.0.0-alpha.7120331332 → 13.0.0-alpha.7222542422

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.
@@ -1,4 +1,5 @@
1
1
  import * as React from "react";
2
+ import * as R from "ramda";
2
3
 
3
4
  import {
4
5
  BaseFocusable as BaseFocusableInterface,
@@ -7,7 +8,6 @@ import {
7
8
 
8
9
  import { createReactRef } from "@applicaster/zapp-react-native-utils/reactUtils";
9
10
  import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
10
- import * as FOCUS_EVENTS from "@applicaster/zapp-react-native-utils/appUtils/focusManager/events";
11
11
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
12
12
 
13
13
  type ScrollDirection = FocusManager.IOS.Direction | FocusManager.Web.Direction;
@@ -131,12 +131,6 @@ export class BaseFocusable<
131
131
  willLoseFocus: FocusManager.FocusEventCB = (focusable, scrollDirection) => {
132
132
  const { willLoseFocus = noop } = this.props;
133
133
  willLoseFocus(focusable, scrollDirection);
134
-
135
- focusManager.invokeHandler?.(
136
- FOCUS_EVENTS.WILL_LOSE_FOCUS,
137
- this,
138
- scrollDirection
139
- );
140
134
  };
141
135
 
142
136
  willReceiveFocus: FocusManager.FocusEventCB = (
@@ -145,12 +139,6 @@ export class BaseFocusable<
145
139
  ) => {
146
140
  const { willReceiveFocus = noop } = this.props;
147
141
  willReceiveFocus(focusable, scrollDirection);
148
-
149
- focusManager.invokeHandler?.(
150
- FOCUS_EVENTS.WILL_RECEIVE_FOCUS,
151
- this,
152
- scrollDirection
153
- );
154
142
  };
155
143
 
156
144
  /**
@@ -163,8 +151,6 @@ export class BaseFocusable<
163
151
  const { onFocus = noop } = this.props;
164
152
  this.setFocusedState(true);
165
153
  onFocus(focusable, scrollDirection);
166
-
167
- focusManager.invokeHandler?.(FOCUS_EVENTS.FOCUS, this, scrollDirection);
168
154
  };
169
155
 
170
156
  /**
@@ -179,12 +165,6 @@ export class BaseFocusable<
179
165
  ) => {
180
166
  const { hasReceivedFocus = noop } = this.props;
181
167
  hasReceivedFocus(focusable, scrollDirection);
182
-
183
- focusManager.invokeHandler?.(
184
- FOCUS_EVENTS.HAS_RECEIVED_FOCUS,
185
- this,
186
- scrollDirection
187
- );
188
168
  };
189
169
 
190
170
  /**
@@ -196,12 +176,6 @@ export class BaseFocusable<
196
176
  hasLostFocus: FocusManager.FocusEventCB = (focusable, scrollDirection) => {
197
177
  const { hasLostFocus = noop } = this.props;
198
178
  hasLostFocus(focusable, scrollDirection);
199
-
200
- focusManager.invokeHandler?.(
201
- FOCUS_EVENTS.HAS_LOST_FOCUS,
202
- this,
203
- scrollDirection
204
- );
205
179
  };
206
180
 
207
181
  /**
@@ -228,7 +202,6 @@ export class BaseFocusable<
228
202
  const { onBlur = noop } = this.props;
229
203
  this.setFocusedState(false);
230
204
  onBlur(focusable, scrollDirection);
231
- focusManager.invokeHandler?.(FOCUS_EVENTS.BLUR, this, scrollDirection);
232
205
  };
233
206
 
234
207
  onPress = (keyEvent?: Nullable<React.MouseEvent>) => {
@@ -269,4 +242,68 @@ export class BaseFocusable<
269
242
  this.setState({ focused });
270
243
  }
271
244
  };
245
+
246
+ /**
247
+ * will invoke the underlying component's focus method
248
+ * @param {Object} scrollDirection
249
+ * @returns {Promise}
250
+ */
251
+ focus(_, scrollDirection) {
252
+ return this.onFocus(this, scrollDirection); // invokeComponentMethod(this, "onFocus", scrollDirection);
253
+ }
254
+
255
+ /**
256
+ * will invoke the underlying component's blur method
257
+ * @param {Object} scrollDirection
258
+ * @returns {Promise}
259
+ */
260
+ blur(
261
+ _,
262
+ scrollDirection?: FocusManager.Web.Direction | FocusManager.IOS.Direction
263
+ ) {
264
+ return this.onBlur(this, scrollDirection);
265
+ }
266
+
267
+ /**
268
+ * Sets the focus on this item. Will trigger sequentially a sequence of
269
+ * functions (willReceiveFocus, focus, hasReceivedFocus). If these functions (defined in the Focusable
270
+ * Item underlying component) return promises, execution will wait before it proceeds to the next. This
271
+ * is useful for triggering sequential operations that specifically require to fully run before or after
272
+ * focus is actually set on that item.
273
+ * @param {string} scrollDirection string representation of the direction of the navigation which landed
274
+ * to this item being focused
275
+ */
276
+ _executeFocusSequence(methodNames, scrollDirection) {
277
+ return R.reduce(
278
+ (sequence, methodName) => {
279
+ const method = this[methodName]; // Access the method by name
280
+
281
+ if (typeof method !== "function") {
282
+ throw new Error(
283
+ `Method '${methodName}' not found or not a function.`
284
+ );
285
+ }
286
+
287
+ return sequence
288
+ .then(() => method.call(this, scrollDirection))
289
+ .catch((e) => {
290
+ throw e; // Re-throw for consistent error handling
291
+ });
292
+ },
293
+ Promise.resolve(),
294
+ methodNames
295
+ );
296
+ }
297
+
298
+ setFocus(scrollDirection) {
299
+ const focusMethods = ["willReceiveFocus", "focus", "hasReceivedFocus"];
300
+
301
+ return this._executeFocusSequence(focusMethods, scrollDirection);
302
+ }
303
+
304
+ setBlur(scrollDirection) {
305
+ const blurMethods = ["willLoseFocus", "blur", "hasLostFocus"];
306
+
307
+ return this._executeFocusSequence(blurMethods, scrollDirection);
308
+ }
272
309
  }
@@ -61,6 +61,7 @@ type Props = {
61
61
  skipFocusManagerRegistration?: boolean;
62
62
  shouldUpdate: boolean;
63
63
  behavior: Behavior;
64
+ componentsMapOffset: number;
64
65
  };
65
66
 
66
67
  type State = {
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import * as R from "ramda";
3
3
  import { View, StyleSheet } from "react-native";
4
4
 
5
- import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
5
+ import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable/FocusableTvOS";
6
6
  import { FocusableCell } from "@applicaster/zapp-react-native-ui-components/Components/FocusableCell";
7
7
  import { getItemType } from "@applicaster/zapp-react-native-utils/navigationUtils";
8
8
  import { SCREEN_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypes";
@@ -10,10 +10,6 @@ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focu
10
10
  import { sendSelectCellEvent } from "@applicaster/zapp-react-native-utils/analyticsUtils";
11
11
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
12
12
  import { CellWithFocusable } from "./CellWithFocusable";
13
- import { getCellState } from "./utils";
14
-
15
- const _getCellState = (focused, selected) =>
16
- getCellState({ focused, selected });
17
13
 
18
14
  type Props = {
19
15
  item: ZappEntry;
@@ -69,6 +65,7 @@ type Props = {
69
65
  isFocusable: boolean;
70
66
  shouldUpdate: boolean;
71
67
  behavior: Behavior;
68
+ componentsMapOffset: number;
72
69
  };
73
70
 
74
71
  type State = {
@@ -183,6 +180,7 @@ export class TvOSCellComponent extends React.Component<Props, State> {
183
180
  groupId,
184
181
  component,
185
182
  index,
183
+ componentsMapOffset,
186
184
  } = this.props;
187
185
 
188
186
  this.setScreenLayout(componentAnchorPointY, screenLayout);
@@ -197,13 +195,11 @@ export class TvOSCellComponent extends React.Component<Props, State> {
197
195
  const extraAnchorPointYOffset =
198
196
  screenLayout?.extraAnchorPointYOffset || 0;
199
197
 
200
- const marginTop = screenLayout?.screenMarginTop || 0;
201
-
202
198
  const totalOffset =
203
199
  headerOffset +
204
- (componentAnchorPointY || 0) +
205
- extraAnchorPointYOffset -
206
- marginTop;
200
+ (componentAnchorPointY || 0) +
201
+ extraAnchorPointYOffset -
202
+ componentsMapOffset || 0;
207
203
 
208
204
  mainOffsetUpdater?.(
209
205
  { tag: this.target },
@@ -251,7 +247,7 @@ export class TvOSCellComponent extends React.Component<Props, State> {
251
247
 
252
248
  const focusableId = R.join("-", [component?.id, id, index]);
253
249
 
254
- const handleFocus = (arg1: any, index: number) => {
250
+ const handleFocus = (arg1: any, index?: number) => {
255
251
  const focusFn = onFocus || noop;
256
252
  focusFn(arg1, index);
257
253
 
@@ -284,7 +280,7 @@ export class TvOSCellComponent extends React.Component<Props, State> {
284
280
  <View onLayout={this.onLayout} style={styles.container}>
285
281
  <Focusable
286
282
  id={focusableId}
287
- groupId={groupId || component?.id}
283
+ groupId={String(groupId || component?.id)}
288
284
  onFocus={handleFocus}
289
285
  onBlur={onBlur || this.onBlur}
290
286
  isParallaxDisabled={this.layout?.width > 1740}
@@ -296,20 +292,18 @@ export class TvOSCellComponent extends React.Component<Props, State> {
296
292
  style={baseCellStyles}
297
293
  isFocusable={isFocusable}
298
294
  >
299
- {(focused) => {
300
- return (
301
- <FocusableCell
302
- {...{
303
- index,
304
- CellRenderer,
305
- item,
306
- focused: this.props.focused || selectedCell || focused,
307
- scrollTo: this.scrollTo,
308
- behavior,
309
- }}
310
- />
311
- );
312
- }}
295
+ {(focused) => (
296
+ <FocusableCell
297
+ {...{
298
+ index,
299
+ CellRenderer,
300
+ item,
301
+ focused: !!(this.props.focused || selectedCell || focused),
302
+ scrollTo: this.scrollTo,
303
+ behavior,
304
+ }}
305
+ />
306
+ )}
313
307
  </Focusable>
314
308
  </View>
315
309
  );
@@ -11,6 +11,7 @@ import { ScreenScrollingContext } from "../../Contexts/ScreenScrollingContext";
11
11
 
12
12
  import { ScreenLayoutContextConsumer } from "../../Contexts/ScreenLayoutContext";
13
13
  import { createContext } from "@applicaster/zapp-react-native-utils/reactUtils/createContext";
14
+ import { withComponentsMapOffsetContextConsumer } from "../../Contexts/ComponentsMapOffsetContext";
14
15
 
15
16
  // TODO | Gallery QB | Extract this
16
17
  export const ScrollInterceptorContext = createContext(
@@ -30,5 +31,6 @@ export const Cell = R.compose(
30
31
  RiverOffsetContext.withConsumer,
31
32
  HorizontalScrollContext.withConsumer,
32
33
  withConsumer,
33
- ScreenLayoutContextConsumer
34
+ ScreenLayoutContextConsumer,
35
+ withComponentsMapOffsetContextConsumer
34
36
  )(Component);
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import * as R from "ramda";
3
2
 
4
3
  import { BaseFocusable } from "../BaseFocusable";
5
4
  import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
@@ -42,8 +41,6 @@ class Focusable extends BaseFocusable<Props> {
42
41
  this.resetLongPressTimeout = this.resetLongPressTimeout.bind(this);
43
42
  this.longPress = this.longPress.bind(this);
44
43
  this.press = this.press.bind(this);
45
- this.focus = this.focus.bind(this);
46
- this.blur = this.blur.bind(this);
47
44
  }
48
45
 
49
46
  /**
@@ -55,37 +52,6 @@ class Focusable extends BaseFocusable<Props> {
55
52
  return this.preferredFocus();
56
53
  }
57
54
 
58
- /**
59
- * Sets the focus on this item. Will trigger sequentially a sequence of
60
- * functions (willReceiveFocus, focus, hasReceivedFocus). If these functions (defined in the Focusable
61
- * Item underlying component) return promises, execution will wait before it proceeds to the next. This
62
- * is useful for triggering sequential operations that specifically require to fully run before or after
63
- * focus is actually set on that item.
64
- * @param {string} scrollDirection string representation of the direction of the navigation which landed
65
- * to this item being focused
66
- */
67
- setFocus(scrollDirection) {
68
- const focusMethods = [
69
- this.willReceiveFocus,
70
- this.focus,
71
- this.hasReceivedFocus,
72
- ];
73
-
74
- const self = this;
75
-
76
- return R.reduce(
77
- (sequence, method) => {
78
- return sequence
79
- .then(() => method.apply(self, [scrollDirection]))
80
- .catch((e) => {
81
- throw e;
82
- });
83
- },
84
- Promise.resolve(),
85
- focusMethods
86
- );
87
- }
88
-
89
55
  startLongPressTimeout() {
90
56
  this.longPressTimeout = setTimeout(() => {
91
57
  this.longPress(null);
@@ -102,26 +68,6 @@ class Focusable extends BaseFocusable<Props> {
102
68
  }
103
69
  }
104
70
 
105
- /**
106
- * will invoke the underlying component's focus method
107
- * @param {Object} scrollDirection
108
- * @returns {Promise}
109
- */
110
- focus(scrollDirection) {
111
- return this.onFocus(this, scrollDirection); // invokeComponentMethod(this, "onFocus", scrollDirection);
112
- }
113
-
114
- /**
115
- * will invoke the underlying component's blur method
116
- * @param {Object} scrollDirection
117
- * @returns {Promise}
118
- */
119
- blur(
120
- scrollDirection?: FocusManager.Web.Direction | FocusManager.IOS.Direction
121
- ) {
122
- return this.onBlur(this, scrollDirection);
123
- }
124
-
125
71
  /**
126
72
  * will invoke the underlying component's press method
127
73
  * @param {Object} keyEvent
@@ -9,7 +9,7 @@ import {
9
9
  focusManager,
10
10
  forceFocusableFocus,
11
11
  } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios";
12
- import { findNodeHandle } from "react-native";
12
+ import { findNodeHandle, ViewStyle } from "react-native";
13
13
 
14
14
  function noop() {}
15
15
 
@@ -35,6 +35,10 @@ type Props = {
35
35
  forceFocus?: boolean;
36
36
  initialFocus?: boolean;
37
37
  onLayout?: (e: any) => void;
38
+ willReceiveFocus: () => void;
39
+ hasReceivedFocus: () => void;
40
+ offsetUpdater: (arg1: string, arg2: number) => number;
41
+ style: ViewStyle;
38
42
  };
39
43
 
40
44
  export class Focusable extends BaseFocusable<Props> {
@@ -90,7 +94,7 @@ export class Focusable extends BaseFocusable<Props> {
90
94
  onBlur(nativeEvent);
91
95
  }
92
96
 
93
- setFocus(direction, callback) {
97
+ setFocus(_direction, callback) {
94
98
  const focusMethods = [
95
99
  { method: this.willReceiveFocus },
96
100
  { method: this.focus, args: [callback] },
@@ -15,6 +15,7 @@ import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
15
15
 
16
16
  import { useParentFocus, useCheckItemIdsForUnique } from "./hooks";
17
17
  import { FocusableListItemWrapper } from "./FocusableListItemWrapper";
18
+ import { FocusableScrollView } from "../FocusableScrollView";
18
19
 
19
20
  const mapIndexed = R.addIndex(R.map);
20
21
 
@@ -54,6 +55,7 @@ export type Props<ItemT> = FlatListProps<ItemT> & {
54
55
  disableNextFocusUp?: boolean;
55
56
  disableNextFocusLeft?: boolean;
56
57
  disableNextFocusRight?: boolean;
58
+ useScrollView?: boolean;
57
59
  } & ParentFocus;
58
60
 
59
61
  function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
@@ -87,8 +89,8 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
87
89
  initialFocusDirection = "down",
88
90
  data = [],
89
91
  // eslint-disable-next-line unused-imports/no-unused-vars
90
- onAllComponentsLoaded, // TODO: re-implement it
91
92
  omitPropsPropagation = [],
93
+ useScrollView = false,
92
94
  } = props;
93
95
 
94
96
  useCheckItemIdsForUnique({ componentId: props.id, items: data });
@@ -274,6 +276,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
274
276
  "initialFocusDirection",
275
277
  "withStateMemory",
276
278
  "useSequentialLoading",
279
+ "useScrollView",
277
280
  ...omitPropsPropagation,
278
281
  ],
279
282
  R.__
@@ -296,15 +299,27 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
296
299
  return (
297
300
  // @ts-ignore
298
301
  <ChildrenFocusDeactivatorView flex={1}>
299
- <FlatList
300
- focusable={false}
301
- scrollEnabled={false}
302
- ref={ref}
303
- {...getFlatListProps(props)}
304
- renderItem={renderItem}
305
- onEndReached={onEndReached}
306
- initialNumToRender={initialNumToRender}
307
- />
302
+ {useScrollView ? (
303
+ <FocusableScrollView
304
+ ref={ref}
305
+ {...getFlatListProps(props)}
306
+ onEndReached={onEndReached}
307
+ initialNumToRender={initialNumToRender}
308
+ renderItem={renderItem}
309
+ focused={focused}
310
+ data={data}
311
+ />
312
+ ) : (
313
+ <FlatList
314
+ focusable={false}
315
+ scrollEnabled={false}
316
+ ref={ref}
317
+ {...getFlatListProps(props)}
318
+ renderItem={renderItem}
319
+ onEndReached={onEndReached}
320
+ initialNumToRender={initialNumToRender}
321
+ />
322
+ )}
308
323
  </ChildrenFocusDeactivatorView>
309
324
  );
310
325
  }
@@ -11,6 +11,13 @@ import {
11
11
  useInitialFocus,
12
12
  } from "@applicaster/zapp-react-native-utils/focusManager";
13
13
 
14
+ export type FocusableScrollViewRenderItem = (info: {
15
+ item: ZappUIComponent;
16
+ index: number;
17
+ focused: boolean;
18
+ parentFocus: ParentFocus;
19
+ }) => React.ReactElement;
20
+
14
21
  export type Props = ScrollViewProps & {
15
22
  id?: number | string;
16
23
  horizontal?: boolean;
@@ -32,17 +39,27 @@ export type Props = ScrollViewProps & {
32
39
  initialFocusDirection?: FocusManager.Android.FocusNavigationDirections;
33
40
  onAllComponentsLoaded?: () => void;
34
41
  omitPropsPropagation?: Array<keyof FlatListProps<any>>;
35
- renderItem: (info: {
36
- item: ZappUIComponent;
37
- index: number;
38
- focused: boolean;
39
- parentFocus: ParentFocus;
40
- }) => React.ReactElement;
42
+ renderItem: FocusableScrollViewRenderItem;
41
43
  } & ParentFocus;
42
44
 
43
45
  type State = boolean[];
44
46
  type Action = { index?: number; isFocusable: boolean; type?: string };
45
47
 
48
+ const unwrapArray = (maybeArray) =>
49
+ Array.isArray(maybeArray) ? maybeArray[0] : maybeArray;
50
+
51
+ function getEntry<T>(data: T | T[], index: unknown): T {
52
+ let entry;
53
+
54
+ if (R.isNil(index)) {
55
+ entry = unwrapArray(data);
56
+ } else if (typeof index === "number") {
57
+ entry = unwrapArray(data[index]);
58
+ }
59
+
60
+ return entry;
61
+ }
62
+
46
63
  const focusableStateReducer = (
47
64
  state: State,
48
65
  { index = null, isFocusable, type = null }: Action
@@ -73,7 +90,7 @@ const extendScrollViewRef = (_ref, childCompsMeasurementsMap) => {
73
90
  };
74
91
 
75
92
  _ref.scrollToIndex = (params) => {
76
- const { index, viewOffset } = params;
93
+ const { index, viewOffset = 0 } = params;
77
94
 
78
95
  const itemByIndex = R.find(R.propEq("index", index))(
79
96
  R.values(childCompsMeasurementsMap)
@@ -129,8 +146,11 @@ function FocusableScrollViewComponent(props: Props, ref) {
129
146
  );
130
147
 
131
148
  const getFocusableEntryId = React.useCallback(
132
- (_entry: ZappEntry, index?: number) => {
133
- const entry = R.isNil(index) ? _entry : data[index];
149
+ (_entry: ZappEntry | null, index?: number) => {
150
+ const entry: { id?: string } = getEntry(
151
+ R.isNil(index) ? _entry : data,
152
+ index
153
+ );
134
154
 
135
155
  return entry ? `${props.id}--${entry?.id}` : undefined;
136
156
  },
@@ -273,11 +293,18 @@ function FocusableScrollViewComponent(props: Props, ref) {
273
293
  const renderItem = React.useCallback(
274
294
  (item, index) => {
275
295
  const renderArgs = { item, index };
276
- const id = `${props.id}--${renderArgs?.item?.id}`;
277
- const nextFocus = getNextFocus(renderArgs?.index);
296
+
297
+ const id = getFocusableEntryId(
298
+ Array.isArray(item) ? item[0] : item,
299
+ index
300
+ );
301
+
302
+ const nextFocus = getNextFocus(index);
278
303
 
279
304
  const onItemLayout = (event) => {
280
- childCompsMeasurementsMap.current[item.id] = {
305
+ childCompsMeasurementsMap.current[
306
+ Array.isArray(item) ? index : item.id
307
+ ] = {
281
308
  index,
282
309
  layout: event.nativeEvent.layout,
283
310
  };
@@ -1,7 +1,5 @@
1
1
  import * as React from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
- import { ScreenLayoutContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenLayoutContext";
4
- import { ifEmptyUseFallback } from "@applicaster/zapp-react-native-utils/cellUtils";
5
3
  import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
6
4
  import { useScreenConfiguration } from "../../River/useScreenConfiguration";
7
5
 
@@ -12,12 +10,15 @@ type Props = {
12
10
  };
13
11
 
14
12
  const styles = StyleSheet.create({
15
- container: { position: "absolute", top: 0, zIndex: 10, width: 1920 },
13
+ container: {
14
+ position: "absolute",
15
+ top: 0,
16
+ zIndex: 10,
17
+ width: 1920,
18
+ },
16
19
  });
17
20
 
18
21
  export const NavBarContainer = ({ children, isVisible, onReady }: Props) => {
19
- const screenLayout = React.useContext(ScreenLayoutContext);
20
- const screenMarginTop = screenLayout?.screenMarginTop || 0;
21
22
  const screen = useCurrentScreenData();
22
23
  const screenConfig = useScreenConfiguration(screen?.id);
23
24
 
@@ -26,9 +27,9 @@ export const NavBarContainer = ({ children, isVisible, onReady }: Props) => {
26
27
  // limits the height of the focusable container of the TopMenuBarTV component
27
28
  // to prevent it from being overlapped by the screen content,
28
29
  // as it makes TopMenuBarTV unfocusable on tvOS
29
- maxHeight: ifEmptyUseFallback(screenConfig?.marginTop, screenMarginTop),
30
+ maxHeight: 1,
30
31
  }),
31
- [screenLayout, screenConfig]
32
+ [screenConfig]
32
33
  );
33
34
 
34
35
  React.useEffect(() => {
@@ -50,7 +50,7 @@ function Image({
50
50
  // @ts-ignore
51
51
  <MemoizedImage
52
52
  style={style as ImageStyle}
53
- onError={() => setErrorState(true)}
53
+ onError={React.useCallback(() => setErrorState(true), [])}
54
54
  source={
55
55
  shouldRenderImg ? withDimensions(source) : defaultPlaceHolderImage
56
56
  }
@@ -8,7 +8,7 @@ import { MasterCellAsyncRenderManager } from "./MasterCellAsyncRenderManager";
8
8
  const layoutMeasure = (viewRef, onMeasure) => {
9
9
  viewRef?.measureLayout?.(
10
10
  findNodeHandle(viewRef),
11
- (x, y, width, height) => {
11
+ (_x, _y, width, height) => {
12
12
  onMeasure({ width, height });
13
13
  },
14
14
  noop
@@ -16,7 +16,7 @@ const layoutMeasure = (viewRef, onMeasure) => {
16
16
  };
17
17
 
18
18
  const regularMeasure = (viewRef, onMeasure) => {
19
- viewRef?.measure?.((x, y, width, height) => {
19
+ viewRef?.measure?.((_x, _y, width, height) => {
20
20
  onMeasure({ width, height });
21
21
  });
22
22
  };
@@ -380,7 +380,7 @@ const PlayerContainerComponent = (props: Props) => {
380
380
  }
381
381
  };
382
382
 
383
- const playerRemoteHandler = (component, event, isLanguageOverlayVisible) => {
383
+ const playerRemoteHandler = (event, isLanguageOverlayVisible) => {
384
384
  const { eventType } = event;
385
385
 
386
386
  if (!isLanguageOverlayVisible && eventType === "menu") {
@@ -623,12 +623,8 @@ const PlayerContainerComponent = (props: Props) => {
623
623
  <PlayerContainerContext.Consumer>
624
624
  {(context) => (
625
625
  <TVEventHandlerComponent
626
- tvEventHandler={(component, event) =>
627
- playerRemoteHandler(
628
- component,
629
- event,
630
- context.isLanguageOverlayVisible
631
- )
626
+ tvEventHandler={(_component, event) =>
627
+ playerRemoteHandler(event, context.isLanguageOverlayVisible)
632
628
  }
633
629
  >
634
630
  <FocusableGroup
@@ -9,11 +9,14 @@ type ContextProps = {
9
9
  setIsLanguageOverlayVisible: (isVisible) => void;
10
10
  setShowComponentsContainer: (isVisible) => void;
11
11
  showComponentsContainer: boolean;
12
+ setIsSeekBarTouch: (isTouch) => void;
13
+ isSeekBarTouch: boolean;
12
14
  };
13
15
 
14
16
  export const PlayerContainerContext = createContext({
15
17
  ignoreOffsetContainer: false,
16
18
  isLanguageOverlayVisible: false,
19
+ isSeekBarTouch: false,
17
20
  } as ContextProps);
18
21
 
19
22
  type Props = {
@@ -40,6 +43,8 @@ export const PlayerContainerContextProvider = ({
40
43
  const [showComponentsContainer, setShowComponentsContainer] =
41
44
  React.useState(true);
42
45
 
46
+ const [isSeekBarTouch, setIsSeekBarTouch] = React.useState(false);
47
+
43
48
  const value = React.useMemo(
44
49
  () => ({
45
50
  ignoreOffsetContainer,
@@ -49,6 +54,8 @@ export const PlayerContainerContextProvider = ({
49
54
  setIsLanguageOverlayVisible,
50
55
  showComponentsContainer,
51
56
  setShowComponentsContainer: inline ? setShowComponentsContainer : null,
57
+ isSeekBarTouch,
58
+ setIsSeekBarTouch,
52
59
  }),
53
60
  [
54
61
  ignoreOffsetContainer,
@@ -58,6 +65,8 @@ export const PlayerContainerContextProvider = ({
58
65
  setIsLanguageOverlayVisible,
59
66
  showComponentsContainer,
60
67
  setShowComponentsContainer,
68
+ isSeekBarTouch,
69
+ setIsSeekBarTouch,
61
70
  ]
62
71
  );
63
72
 
@@ -1,4 +1,9 @@
1
+ import { compose } from "ramda";
1
2
  import { River as RiverComponent } from "./River";
2
3
  import { withTvEventHandler } from "./withTVEventHandler";
4
+ import { withComponentsMapOffsetContext } from "../../../Contexts/ComponentsMapOffsetContext";
3
5
 
4
- export const River = withTvEventHandler(RiverComponent);
6
+ export const River = compose(
7
+ withTvEventHandler,
8
+ withComponentsMapOffsetContext
9
+ )(RiverComponent);
@@ -62,7 +62,10 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
62
62
  } = useModalAnimationContext();
63
63
 
64
64
  const [enableGesture, setIEnableGesture] = React.useState<boolean>(true);
65
- const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
65
+
66
+ const { isLanguageOverlayVisible, isSeekBarTouch } = React.useContext(
67
+ PlayerContainerContext
68
+ );
66
69
 
67
70
  const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
68
71
  useNavigation();
@@ -80,6 +83,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
80
83
  enableGesture &&
81
84
  !isLanguageOverlayVisible &&
82
85
  isNotMinimizeMaximazeAnimation &&
86
+ !isSeekBarTouch &&
83
87
  (isMaximazedModal || isMinimizedModal);
84
88
 
85
89
  const isAudioItem = React.useMemo(
@@ -41,7 +41,10 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
41
41
  videoModalState: { mode: videoModalMode },
42
42
  } = useNavigation();
43
43
 
44
- const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
44
+ const { isLanguageOverlayVisible, isSeekBarTouch } = React.useContext(
45
+ PlayerContainerContext
46
+ );
47
+
45
48
  const isMaximazedModal = videoModalMode === "MAXIMIZED";
46
49
  const isMinimizedModal = videoModalMode === "MINIMIZED";
47
50
 
@@ -52,6 +55,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
52
55
  const isEnablePanGesture =
53
56
  !isLanguageOverlayVisible &&
54
57
  isNotMinimizeMaximazeAnimation &&
58
+ !isSeekBarTouch &&
55
59
  (isMaximazedModal || isMinimizedModal);
56
60
 
57
61
  const onGestureEvent = Animated.event(
@@ -77,7 +77,7 @@ export const AnimationView = ({
77
77
  const measureView = React.useCallback(() => {
78
78
  if (isTabletLandscape && tabletLandscapePlayerTopPosition === 0) {
79
79
  animationComponentRef.current.measure(
80
- (x, y, width, height, pageX, pageY) => {
80
+ (_x, _y, _width, _height, _pageX, pageY) => {
81
81
  setTabletLandscapePlayerTopPosition(pageY - 20);
82
82
  }
83
83
  );
@@ -0,0 +1,41 @@
1
+ import React, { PropsWithChildren } from "react";
2
+
3
+ export const ComponentsMapOffsetContext = React.createContext({
4
+ setComponentsMapOffset: (_offset: number) => void 0,
5
+ componentsMapOffset: 0,
6
+ });
7
+
8
+ export const ComponentsMapOffsetContextProvider = ({
9
+ children,
10
+ }: PropsWithChildren<{}>) => {
11
+ const [componentsMapOffset, setComponentsMapOffset] = React.useState(0);
12
+
13
+ const contextValue = {
14
+ componentsMapOffset,
15
+ setComponentsMapOffset,
16
+ };
17
+
18
+ return (
19
+ <ComponentsMapOffsetContext.Provider value={contextValue}>
20
+ {children}
21
+ </ComponentsMapOffsetContext.Provider>
22
+ );
23
+ };
24
+
25
+ export const withComponentsMapOffsetContext = (Component: any) =>
26
+ function ComponentsMapOffsetContextProviderWrapper(props: {}) {
27
+ return (
28
+ <ComponentsMapOffsetContextProvider>
29
+ <Component {...props} />
30
+ </ComponentsMapOffsetContextProvider>
31
+ );
32
+ };
33
+
34
+ export const withComponentsMapOffsetContextConsumer = (Component: any) =>
35
+ function ComponentsMapOffsetContextConsumerWrapper(props: {}) {
36
+ const { componentsMapOffset } = React.useContext(
37
+ ComponentsMapOffsetContext
38
+ );
39
+
40
+ return <Component {...props} componentsMapOffset={componentsMapOffset} />;
41
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "13.0.0-alpha.7120331332",
3
+ "version": "13.0.0-alpha.7222542422",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -34,20 +34,26 @@
34
34
  "redux-mock-store": "^1.5.3"
35
35
  },
36
36
  "dependencies": {
37
- "@applicaster/applicaster-types": "13.0.0-alpha.7120331332",
38
- "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.7120331332",
39
- "@applicaster/zapp-react-native-redux": "13.0.0-alpha.7120331332",
40
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.7120331332",
37
+ "@applicaster/applicaster-types": "13.0.0-alpha.7222542422",
38
+ "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.7222542422",
39
+ "@applicaster/zapp-react-native-redux": "13.0.0-alpha.7222542422",
40
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.7222542422",
41
41
  "promise": "^8.3.0",
42
42
  "react-router-native": "^5.1.2",
43
43
  "url": "^0.11.0",
44
44
  "uuid": "^3.3.2"
45
45
  },
46
46
  "peerDependencies": {
47
+ "@applicaster/zapp-pipes-v2-client": "*",
47
48
  "@react-native-community/netinfo": "*",
49
+ "@types/node": "*",
50
+ "immer": "*",
48
51
  "react": "17.0.2",
49
52
  "react-native": "0.68.6",
50
53
  "react-native-safe-area-context": "*",
51
- "react-native-svg": "*"
54
+ "react-native-svg": "*",
55
+ "uglify-js": "*",
56
+ "validate-color": "*",
57
+ "zustand": "*"
52
58
  }
53
59
  }