@applicaster/zapp-react-native-utils 15.0.0-alpha.4368022015 → 15.0.0-alpha.4413958104

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 (48) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +3 -6
  2. package/actionsExecutor/feedDecorator.ts +6 -6
  3. package/adsUtils/index.ts +2 -2
  4. package/analyticsUtils/README.md +1 -1
  5. package/appUtils/HooksManager/index.ts +10 -10
  6. package/appUtils/accessibilityManager/const.ts +4 -0
  7. package/appUtils/accessibilityManager/hooks.ts +20 -13
  8. package/appUtils/accessibilityManager/index.ts +28 -1
  9. package/appUtils/accessibilityManager/utils.ts +36 -5
  10. package/appUtils/keyCodes/keys/keys.web.ts +1 -4
  11. package/appUtils/orientationHelper.ts +2 -4
  12. package/appUtils/platform/platformUtils.ts +115 -16
  13. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +94 -4
  14. package/appUtils/playerManager/OverlayObserver/utils.ts +32 -20
  15. package/appUtils/playerManager/player.ts +4 -0
  16. package/appUtils/playerManager/playerNative.ts +29 -16
  17. package/appUtils/playerManager/usePlayerState.tsx +14 -2
  18. package/cellUtils/index.ts +32 -0
  19. package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
  20. package/manifestUtils/defaultManifestConfigurations/player.js +75 -1
  21. package/manifestUtils/keys.js +21 -0
  22. package/manifestUtils/sharedConfiguration/screenPicker/utils.js +1 -0
  23. package/manifestUtils/tvAction/container/index.js +1 -1
  24. package/package.json +2 -2
  25. package/playerUtils/usePlayerTTS.ts +8 -3
  26. package/pluginUtils/index.ts +4 -0
  27. package/reactHooks/advertising/index.ts +2 -2
  28. package/reactHooks/debugging/__tests__/index.test.js +4 -4
  29. package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
  30. package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +3 -0
  31. package/reactHooks/feed/useEntryScreenId.ts +2 -2
  32. package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx} +105 -25
  33. package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
  34. package/reactHooks/navigation/index.ts +7 -6
  35. package/reactHooks/navigation/useRoute.ts +8 -6
  36. package/reactHooks/player/TVSeekControlller/TVSeekController.ts +27 -10
  37. package/reactHooks/resolvers/useCellResolver.ts +6 -2
  38. package/reactHooks/resolvers/useComponentResolver.ts +8 -2
  39. package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +10 -2
  40. package/reactHooks/screen/useTargetScreenData.ts +4 -2
  41. package/reactHooks/state/useRivers.ts +1 -1
  42. package/reactHooks/usePluginConfiguration.ts +2 -2
  43. package/testUtils/index.tsx +29 -20
  44. package/utils/__tests__/mapAccum.test.ts +73 -0
  45. package/utils/__tests__/selectors.test.ts +124 -0
  46. package/utils/index.ts +5 -0
  47. package/utils/mapAccum.ts +23 -0
  48. package/utils/selectors.ts +46 -0
@@ -335,6 +335,20 @@ function getPlayerConfiguration({ platform, version }) {
335
335
  };
336
336
 
337
337
  if (isTV(platform)) {
338
+ localizations.fields.push({
339
+ key: "back_to_live_label",
340
+ label: "Back to live label",
341
+ initial_value: "Back To Live",
342
+ type: "text_input",
343
+ });
344
+
345
+ localizations.fields.push({
346
+ key: "start_over_label",
347
+ label: "Start over label",
348
+ initial_value: "Start Over",
349
+ type: "text_input",
350
+ });
351
+
338
352
  styles.fields.push(
339
353
  fieldsGroup("Always Show Scrub Bar & Timestamp", "", [
340
354
  {
@@ -447,7 +461,7 @@ function getPlayerConfiguration({ platform, version }) {
447
461
  ),
448
462
  fieldsGroup(
449
463
  "Skip Button",
450
- "This section allows you to configure the skip button styles for tv",
464
+ "This section allows you to configure the skip button behaviour",
451
465
  [
452
466
  {
453
467
  type: "switch",
@@ -464,6 +478,12 @@ function getPlayerConfiguration({ platform, version }) {
464
478
  label: "Persistent Button Toggle",
465
479
  initial_value: true,
466
480
  },
481
+ ]
482
+ ),
483
+ fieldsGroup(
484
+ "Labeled Button Style",
485
+ "This section allows you to configure the labeled button styles",
486
+ [
467
487
  {
468
488
  type: "color_picker_rgba",
469
489
  label_tooltip: "",
@@ -619,6 +639,44 @@ function getPlayerConfiguration({ platform, version }) {
619
639
  );
620
640
  }
621
641
 
642
+ if (isTV(platform)) {
643
+ general.fields.push(
644
+ {
645
+ key: "liveSeekingEnabled",
646
+ label: "Live Seeking Enabled",
647
+ initial_value: false,
648
+ type: "switch",
649
+ label_tooltip: "Enable Live Seek",
650
+ },
651
+ {
652
+ key: "minimumAllowedSeekableDurationInSeconds",
653
+ label: "Minimum allowed seekable duration in seconds",
654
+ initial_value: 300,
655
+ type: "number_input",
656
+ label_tooltip:
657
+ "If duration less than this value, player will disable 'liveSeekingEnabled' value",
658
+ },
659
+ {
660
+ key: "live_image",
661
+ label: "Live badge",
662
+ type: "uploader",
663
+ label_tooltip: "Override default live badge / icon",
664
+ },
665
+ {
666
+ key: "live_width",
667
+ label: "Live badge width",
668
+ type: "number_input",
669
+ initial_value: 85,
670
+ },
671
+ {
672
+ key: "live_height",
673
+ label: "Live badge height",
674
+ type: "number_input",
675
+ initial_value: 50,
676
+ }
677
+ );
678
+ }
679
+
622
680
  if (isMobile(platform)) {
623
681
  general.fields.push(
624
682
  {
@@ -3429,6 +3487,22 @@ function getPlayerConfiguration({ platform, version }) {
3429
3487
  label_tooltip:
3430
3488
  "This field allows you to override the player configuration / initialization options. i.e. html5: { vhs: { limitRenditionByPlayerDimensions: false } } Please ensure your configuration matches the player you are targeting, and that it is a valid json. See config options here: https://videojs.com/guides/options/",
3431
3489
  },
3490
+ {
3491
+ key: "advanced_player_styles",
3492
+ label: "Advanced Player Styles",
3493
+ type: "text_input",
3494
+ multiline: true,
3495
+ initial_value: `.vjs-text-track-cue {
3496
+ inset: unset !important;
3497
+ top: 94% !important;
3498
+ bottom: 0 !important;
3499
+ left: 0 !important;
3500
+ right: 0 !important;
3501
+ width: 100% !important;
3502
+ }`,
3503
+ label_tooltip:
3504
+ "This field allows you to inject custom CSS styles to override default player styles. The styles will be injected into the document head and can be used to customize the appearance of the player. Leave empty to use only default styles.",
3505
+ },
3432
3506
  {
3433
3507
  key: "use_dashjs_player",
3434
3508
  label: "Use Enhanced Player for DASH streams",
@@ -959,6 +959,27 @@ const TV_CELL_LABEL_FIELDS = [
959
959
  rules: "conditional",
960
960
  conditions: [{ key: "switch", section: "styles", value: true }],
961
961
  },
962
+ {
963
+ type: ZAPPIFEST_FIELDS.font_selector.roku,
964
+ suffix: "roku font family",
965
+ tooltip: "",
966
+ rules: "conditional",
967
+ conditions: [{ key: "switch", section: "styles", value: true }],
968
+ },
969
+ {
970
+ type: ZAPPIFEST_FIELDS.number_input,
971
+ suffix: "roku font size",
972
+ tooltip: "",
973
+ rules: "conditional",
974
+ conditions: [{ key: "switch", section: "styles", value: true }],
975
+ },
976
+ {
977
+ type: ZAPPIFEST_FIELDS.number_input,
978
+ suffix: "roku line height",
979
+ tooltip: "",
980
+ rules: "conditional",
981
+ conditions: [{ key: "switch", section: "styles", value: true }],
982
+ },
962
983
  {
963
984
  type: ZAPPIFEST_FIELDS.select,
964
985
  suffix: "text alignment",
@@ -3,6 +3,7 @@ const defaultPlatforms = {
3
3
  android_tv: "Android TV",
4
4
  lg_tv: "LG TV",
5
5
  samsung_tv: "Samsung TV",
6
+ roku: "Roku TV",
6
7
  };
7
8
 
8
9
  const global_defaults = {
@@ -38,7 +38,7 @@ function tvActionButtonsContainer({ label, description, defaults }) {
38
38
  generateFieldsFromDefaultsWithoutPrefixedLabel(
39
39
  label,
40
40
  defaults,
41
- tvActionButtonContainerFields(defaults["position"])
41
+ tvActionButtonContainerFields(defaults.position)
42
42
  )
43
43
  );
44
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "15.0.0-alpha.4368022015",
3
+ "version": "15.0.0-alpha.4413958104",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "homepage": "https://github.com/applicaster/quickbrick#readme",
29
29
  "dependencies": {
30
- "@applicaster/applicaster-types": "15.0.0-alpha.4368022015",
30
+ "@applicaster/applicaster-types": "15.0.0-alpha.4413958104",
31
31
  "buffer": "^5.2.1",
32
32
  "camelize": "^1.0.0",
33
33
  "dayjs": "^1.11.10",
@@ -1,14 +1,19 @@
1
1
  import * as React from "react";
2
2
  import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer";
3
- import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
3
+ import {
4
+ useAccessibilityManager,
5
+ useAccessibilityState,
6
+ } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
4
7
  import { PlayerTTS } from "@applicaster/zapp-react-native-utils/playerUtils/PlayerTTS";
5
8
 
6
9
  export const usePlayerTTS = () => {
7
10
  const player = usePlayer();
8
11
  const accessibilityManager = useAccessibilityManager({});
12
+ const accessibilityState = useAccessibilityState();
13
+ const isScreenReaderEnabled = accessibilityState.screenReaderEnabled;
9
14
 
10
15
  React.useEffect(() => {
11
- if (player && accessibilityManager) {
16
+ if (player && accessibilityManager && isScreenReaderEnabled) {
12
17
  const playerTTS = new PlayerTTS(player, accessibilityManager);
13
18
  const unsubscribe = playerTTS.init();
14
19
 
@@ -17,5 +22,5 @@ export const usePlayerTTS = () => {
17
22
  playerTTS.destroy();
18
23
  };
19
24
  }
20
- }, [player, accessibilityManager]);
25
+ }, [player, accessibilityManager, isScreenReaderEnabled]);
21
26
  };
@@ -6,6 +6,7 @@ import { deprecationMessage } from "../appUtils";
6
6
 
7
7
  import { pluginUtilsLogger } from "./logger";
8
8
  import { platformSelect } from "../reactUtils";
9
+ import { get } from "../utils";
9
10
 
10
11
  type PluginModule = any;
11
12
  type Plugin = {
@@ -254,3 +255,6 @@ const getPluginType = R.pathOr("unknown_plugin_type", [
254
255
 
255
256
  export const isPlayerPlugin = (routeState): boolean =>
256
257
  getPluginType(routeState) === "player";
258
+
259
+ export const getPluginModuleUrlScheme = (plugin) =>
260
+ get(plugin, ["module", "urlScheme"]);
@@ -3,7 +3,7 @@ import { View } from "react-native";
3
3
  import * as R from "ramda";
4
4
 
5
5
  import { useNavigation } from "../navigation";
6
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
+ import { usePlugins } from "@applicaster/zapp-react-native-redux/hooks";
7
7
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
8
8
  import { dismissModal, openModal } from "../../modalState";
9
9
 
@@ -16,7 +16,7 @@ const ModalContainer = platformSelect({
16
16
 
17
17
  export function useAdvertisingInterstitial() {
18
18
  const { screenData, currentRoute } = useNavigation();
19
- const { plugins } = usePickFromState();
19
+ const plugins = usePlugins();
20
20
 
21
21
  return useEffect(() => {
22
22
  // TODD: typing problem: fix any type
@@ -27,20 +27,20 @@ describe("Debug utils", () => {
27
27
  it("should create new timer if timer with a label does not exist", () => {
28
28
  performanceNowMock.mockReturnValue(1000);
29
29
  time("timer1");
30
- expect(timers["timer1"]).toBeDefined();
31
- expect(timers["timer1"].startTime).toBe(1000);
30
+ expect(timers.timer1).toBeDefined();
31
+ expect(timers.timer1.startTime).toBe(1000);
32
32
  });
33
33
 
34
34
  it("should update start time of timer if timer with a label exists", () => {
35
35
  // First call to time()
36
36
  performanceNowMock.mockReturnValue(1000);
37
37
  time("timer1");
38
- const previousStartTime = timers["timer1"].startTime;
38
+ const previousStartTime = timers.timer1.startTime;
39
39
 
40
40
  // Second call to time()
41
41
  performanceNowMock.mockReturnValue(2000);
42
42
  time("timer1");
43
- const currentStartTime = timers["timer1"].startTime;
43
+ const currentStartTime = timers.timer1.startTime;
44
44
 
45
45
  expect(previousStartTime).toBe(1000);
46
46
  expect(currentStartTime).toBe(2000);
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
3
2
  import { useIsTablet } from "./useIsTablet";
3
+ import { useAppData } from "@applicaster/zapp-react-native-redux";
4
4
 
5
5
  export const useMemoizedIsTablet = () => {
6
6
  const isTablet = useIsTablet();
@@ -14,9 +14,9 @@ export const useMemoizedIsTablet = () => {
14
14
  };
15
15
 
16
16
  export const useIsTabletLandscape = (): boolean => {
17
- const { appData } = usePickFromState(["appData"]);
17
+ const { isTabletPortrait } = useAppData();
18
18
 
19
19
  const isTablet = useIsTablet();
20
20
 
21
- return isTablet && !appData.isTabletPortrait;
21
+ return isTablet && !isTabletPortrait;
22
22
  };
@@ -10,6 +10,9 @@ describe("useEntryScreenId", () => {
10
10
  const mappedScreenId = "mapped-id";
11
11
 
12
12
  const initialState = {
13
+ rivers: {
14
+ [mappedScreenId]: { id: mappedScreenId, type: "any" },
15
+ },
13
16
  contentTypes: { mappedEntry: { screen_id: mappedScreenId } },
14
17
  };
15
18
 
@@ -1,7 +1,7 @@
1
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
1
+ import { useContentTypes } from "@applicaster/zapp-react-native-redux";
2
2
 
3
3
  export const useEntryScreenId = (entry?: ZappEntry): string | undefined => {
4
- const { contentTypes } = usePickFromState("contentTypes");
4
+ const contentTypes = useContentTypes();
5
5
 
6
6
  if (!entry) {
7
7
  return;
@@ -1,16 +1,10 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import React from "react";
2
+ import { renderHook } from "@testing-library/react-native";
2
3
  import { Dimensions, StatusBar } from "react-native";
3
4
  import { useDimensions } from "../useDimensions";
4
- import { usePickFromState } from "@applicaster/zapp-react-native-redux";
5
5
 
6
6
  import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive";
7
-
8
- jest.mock("@applicaster/zapp-react-native-redux/hooks", () => {
9
- return {
10
- ...jest.requireActual("@applicaster/zapp-react-native-redux/hooks"),
11
- usePickFromState: jest.fn(),
12
- };
13
- });
7
+ import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
14
8
 
15
9
  jest.mock(
16
10
  "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive",
@@ -42,12 +36,22 @@ describe("useDimensions", () => {
42
36
 
43
37
  beforeEach(() => {
44
38
  StatusBar.currentHeight = 20;
45
- (usePickFromState as jest.Mock).mockReturnValue({ appData: mockAppData });
46
39
  });
47
40
 
48
41
  it("returns correct initial dimensions", () => {
49
- const { result } = renderHook(() =>
50
- useDimensions("window", { fullDimensions: false })
42
+ const { result } = renderHook(
43
+ () => useDimensions("window", { fullDimensions: false }),
44
+ {
45
+ wrapper: ({ children }) => (
46
+ <WrappedWithProviders
47
+ store={{
48
+ appData: mockAppData,
49
+ }}
50
+ >
51
+ {children}
52
+ </WrappedWithProviders>
53
+ ),
54
+ }
51
55
  );
52
56
 
53
57
  expect(result.current).toMatchObject({
@@ -56,7 +60,17 @@ describe("useDimensions", () => {
56
60
  });
57
61
 
58
62
  it("calls handler on mount", () => {
59
- renderHook(() => useDimensions("window", { fullDimensions: false }));
63
+ renderHook(() => useDimensions("window", { fullDimensions: false }), {
64
+ wrapper: ({ children }) => (
65
+ <WrappedWithProviders
66
+ store={{
67
+ appData: mockAppData,
68
+ }}
69
+ >
70
+ {children}
71
+ </WrappedWithProviders>
72
+ ),
73
+ });
60
74
 
61
75
  expect(Dimensions.addEventListener).toHaveBeenCalledWith(
62
76
  "change",
@@ -65,12 +79,23 @@ describe("useDimensions", () => {
65
79
  });
66
80
 
67
81
  it("calls handler on isActive change", () => {
68
- const { rerender } = renderHook(() =>
69
- useDimensions("window", { fullDimensions: false })
82
+ const { rerender } = renderHook(
83
+ () => useDimensions("window", { fullDimensions: false }),
84
+ {
85
+ wrapper: ({ children }) => (
86
+ <WrappedWithProviders
87
+ store={{
88
+ appData: mockAppData,
89
+ }}
90
+ >
91
+ {children}
92
+ </WrappedWithProviders>
93
+ ),
94
+ }
70
95
  );
71
96
 
72
97
  (useIsScreenActive as jest.Mock).mockReturnValue(false);
73
- rerender();
98
+ rerender({});
74
99
 
75
100
  expect(Dimensions.addEventListener).toHaveBeenCalledWith(
76
101
  "change",
@@ -79,8 +104,19 @@ describe("useDimensions", () => {
79
104
  });
80
105
 
81
106
  it("handles fullDimensions option", () => {
82
- const { result } = renderHook(() =>
83
- useDimensions("window", { fullDimensions: true })
107
+ const { result } = renderHook(
108
+ () => useDimensions("window", { fullDimensions: true }),
109
+ {
110
+ wrapper: ({ children }) => (
111
+ <WrappedWithProviders
112
+ store={{
113
+ appData: mockAppData,
114
+ }}
115
+ >
116
+ {children}
117
+ </WrappedWithProviders>
118
+ ),
119
+ }
84
120
  );
85
121
 
86
122
  expect(result.current).toMatchObject({
@@ -91,8 +127,19 @@ describe("useDimensions", () => {
91
127
  });
92
128
 
93
129
  it("handles excludeStatusBar option", () => {
94
- const { result } = renderHook(() =>
95
- useDimensions("window", { excludeStatusBar: true })
130
+ const { result } = renderHook(
131
+ () => useDimensions("window", { excludeStatusBar: true }),
132
+ {
133
+ wrapper: ({ children }) => (
134
+ <WrappedWithProviders
135
+ store={{
136
+ appData: mockAppData,
137
+ }}
138
+ >
139
+ {children}
140
+ </WrappedWithProviders>
141
+ ),
142
+ }
96
143
  );
97
144
 
98
145
  expect(result.current.height).toBe(
@@ -101,8 +148,19 @@ describe("useDimensions", () => {
101
148
  });
102
149
 
103
150
  it("handles rounded option", () => {
104
- const { result } = renderHook(() =>
105
- useDimensions("window", { rounded: true })
151
+ const { result } = renderHook(
152
+ () => useDimensions("window", { rounded: true }),
153
+ {
154
+ wrapper: ({ children }) => (
155
+ <WrappedWithProviders
156
+ store={{
157
+ appData: mockAppData,
158
+ }}
159
+ >
160
+ {children}
161
+ </WrappedWithProviders>
162
+ ),
163
+ }
106
164
  );
107
165
 
108
166
  expect(result.current.width).toBe(Math.ceil(mockDimensions.width));
@@ -110,8 +168,19 @@ describe("useDimensions", () => {
110
168
  });
111
169
 
112
170
  it("handles deviceInfo option", () => {
113
- const { result } = renderHook(() =>
114
- useDimensions("window", { deviceInfo: true })
171
+ const { result } = renderHook(
172
+ () => useDimensions("window", { deviceInfo: true }),
173
+ {
174
+ wrapper: ({ children }) => (
175
+ <WrappedWithProviders
176
+ store={{
177
+ appData: mockAppData,
178
+ }}
179
+ >
180
+ {children}
181
+ </WrappedWithProviders>
182
+ ),
183
+ }
115
184
  );
116
185
 
117
186
  expect(result.current.deviceInfo).toMatchObject({
@@ -121,7 +190,18 @@ describe("useDimensions", () => {
121
190
 
122
191
  it("logs deprecation warning when fullDimensions is boolean", () => {
123
192
  const consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation();
124
- renderHook(() => useDimensions("window", true));
193
+
194
+ renderHook(() => useDimensions("window", true), {
195
+ wrapper: ({ children }) => (
196
+ <WrappedWithProviders
197
+ store={{
198
+ appData: mockAppData,
199
+ }}
200
+ >
201
+ {children}
202
+ </WrappedWithProviders>
203
+ ),
204
+ });
125
205
 
126
206
  expect(consoleWarnSpy).toHaveBeenCalledWith(
127
207
  "Deprecation Warning\nSecond argument is now the options object. {fullDimensions: boolean, ...}"
@@ -3,7 +3,7 @@ import { useLayoutEffect, useMemo, useRef, useState } from "react";
3
3
  import * as R from "ramda";
4
4
 
5
5
  import { Dimensions, Platform, StatusBar } from "react-native";
6
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
+ import { useAppData } from "@applicaster/zapp-react-native-redux/hooks";
7
7
 
8
8
  import { isTV } from "../../../reactUtils";
9
9
 
@@ -37,7 +37,7 @@ export const useDimensions: UseDimensions = (
37
37
  ) => {
38
38
  const statusBarHeight = StatusBar?.currentHeight;
39
39
  const isActive = useIsScreenActive();
40
- const { appData } = usePickFromState(["appData"]);
40
+ const appData = useAppData();
41
41
 
42
42
  if (typeof fullDimensions === "boolean") {
43
43
  // eslint-disable-next-line no-console
@@ -3,7 +3,7 @@ import { BackHandler } from "react-native";
3
3
 
4
4
  import {
5
5
  useContentTypes,
6
- usePickFromState,
6
+ usePlugins,
7
7
  } from "@applicaster/zapp-react-native-redux/hooks";
8
8
  import { HooksManager } from "@applicaster/zapp-react-native-utils/appUtils/HooksManager";
9
9
 
@@ -16,6 +16,8 @@ import { useConnectionInfo } from "../connection";
16
16
 
17
17
  import { isTV, isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
18
18
  import { useNavbarState } from "../screen";
19
+ import { useRivers } from "../state";
20
+ import { useLayoutVersion } from "../layout";
19
21
 
20
22
  export { useNavigation } from "./useNavigation";
21
23
 
@@ -164,11 +166,10 @@ export const useZappHooksForEntry = (
164
166
  setIsRunningInBackground,
165
167
  }: HookModalContextT = useContext(ZappHookModalContext.ReactContext);
166
168
 
167
- const {
168
- appData: { layoutVersion },
169
- rivers,
170
- plugins,
171
- } = usePickFromState(["appData", "rivers", "plugins"]);
169
+ const plugins = usePlugins();
170
+ const rivers = useRivers();
171
+
172
+ const layoutVersion = useLayoutVersion();
172
173
 
173
174
  const contentTypes = useContentTypes();
174
175
 
@@ -3,7 +3,10 @@
3
3
 
4
4
  import { useContext } from "react";
5
5
 
6
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
+ import {
7
+ useContentTypes,
8
+ usePlugins,
9
+ } from "@applicaster/zapp-react-native-redux/hooks";
7
10
 
8
11
  import { legacyScreenData } from "@applicaster/quick-brick-core/App/NavigationProvider/utils";
9
12
 
@@ -14,6 +17,7 @@ import { useNavigation } from "./useNavigation";
14
17
  import { useModalStoreState } from "../../modalState";
15
18
  import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
16
19
  import { usePathname } from "./usePathname";
20
+ import { useRivers } from "../state";
17
21
 
18
22
  // starts with modal/
19
23
  const isModalPathname = (pathname: string) => /^modal\//.test(pathname);
@@ -42,11 +46,9 @@ export const useRoute = (
42
46
  ? legacyScreenData(screenContext)
43
47
  : screenContext;
44
48
 
45
- const { plugins, contentTypes, rivers } = usePickFromState([
46
- "plugins",
47
- "rivers",
48
- "contentTypes",
49
- ]);
49
+ const plugins = usePlugins();
50
+ const rivers = useRivers();
51
+ const contentTypes = useContentTypes();
50
52
 
51
53
  const modalState = useModalStoreState();
52
54
 
@@ -147,17 +147,34 @@ export class TVSeekController
147
147
 
148
148
  let targetPos = currentPos;
149
149
 
150
- if (this.currentSeekType === SEEK_TYPE.FORWARD) {
151
- targetPos = Math.min(
152
- currentPos + offset,
153
- this.playerController.getSeekableDuration()
154
- );
155
- } else if (this.currentSeekType === SEEK_TYPE.REWIND) {
156
- targetPos = Math.max(0, currentPos - offset);
150
+ const isLive = this.playerController.isLive();
151
+
152
+ if (isLive) {
153
+ if (this.currentSeekType === SEEK_TYPE.REWIND) {
154
+ targetPos = Math.min(
155
+ currentPos + offset,
156
+ this.playerController.getSeekableDuration()
157
+ );
158
+ } else if (this.currentSeekType === SEEK_TYPE.FORWARD) {
159
+ targetPos = Math.max(0, currentPos - offset);
160
+ } else {
161
+ log_warning(
162
+ `TVSeekController: handleDelayedSeek - invalid seek type: ${this.currentSeekType}`
163
+ );
164
+ }
157
165
  } else {
158
- log_warning(
159
- `TVSeekController: handleDelayedSeek - invalid seek type: ${this.currentSeekType}`
160
- );
166
+ if (this.currentSeekType === SEEK_TYPE.FORWARD) {
167
+ targetPos = Math.min(
168
+ currentPos + offset,
169
+ this.playerController.getSeekableDuration()
170
+ );
171
+ } else if (this.currentSeekType === SEEK_TYPE.REWIND) {
172
+ targetPos = Math.max(0, currentPos - offset);
173
+ } else {
174
+ log_warning(
175
+ `TVSeekController: handleDelayedSeek - invalid seek type: ${this.currentSeekType}`
176
+ );
177
+ }
161
178
  }
162
179
 
163
180
  log_debug(
@@ -3,7 +3,10 @@ import memoizee from "memoizee";
3
3
  import * as R from "ramda";
4
4
 
5
5
  import { CellRendererResolver } from "@applicaster/zapp-react-native-ui-components/Components/CellRendererResolver";
6
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
+ import {
7
+ usePlugins,
8
+ useCellStyles,
9
+ } from "@applicaster/zapp-react-native-redux";
7
10
  import { useDimensions } from "../layout";
8
11
  import { useIsRTL } from "../../localizationUtils";
9
12
 
@@ -53,7 +56,8 @@ export function useCellResolver({
53
56
  updateForInactiveScreens: false,
54
57
  });
55
58
 
56
- const { plugins, cellStyles } = usePickFromState(["plugins", "cellStyles"]);
59
+ const plugins = usePlugins();
60
+ const cellStyles = useCellStyles();
57
61
  const isRTL = useIsRTL();
58
62
 
59
63
  const options = {