@applicaster/quick-brick-core 15.0.0-rc.13 → 15.0.0-rc.131

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 (30) hide show
  1. package/App/ActionSetters/index.ts +5 -4
  2. package/App/ActionsProvider/ActionsProvider.tsx +6 -1
  3. package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/useOpenSchemeHandler.test.tsx +12 -27
  4. package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/usePresentSchemeHandler.test.tsx +72 -35
  5. package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/useUrlSchemeHandler.test.tsx +197 -104
  6. package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/useOpenSchemeHandler/index.ts +4 -7
  7. package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/usePresentSchemeHandler.ts +14 -12
  8. package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/useUrlSchemeHandler.ts +42 -30
  9. package/App/DeepLinking/URLSchemeHandler/URLSchemeHandler.tsx +4 -1
  10. package/App/DeepLinking/URLSchemeHandler/__tests__/URLSchemeHandler.test.tsx +20 -13
  11. package/App/DeepLinking/URLSchemeListener/URLSchemeContextProvider.tsx +59 -0
  12. package/App/DeepLinking/URLSchemeListener/index.tsx +3 -4
  13. package/App/DeepLinking/helpers/index.ts +3 -3
  14. package/App/ErrorBoundary/__tests__/store.test.js +1 -1
  15. package/App/ModalProvider/ModalBottomSheet/ModalBottomSheetFrame.tsx +6 -1
  16. package/App/NavigationProvider/Loader.tsx +3 -4
  17. package/App/NavigationProvider/NavigationProvider.tsx +29 -40
  18. package/App/NavigationProvider/ScreenHooks/usePluginScreenHooks.ts +2 -2
  19. package/App/NavigationProvider/__tests__/navigationProvider.test.tsx +193 -152
  20. package/App/NavigationProvider/navigator/selectors.ts +21 -5
  21. package/App/NetworkStatusProvider/NetworkStatusProvider.tsx +2 -2
  22. package/App/NetworkStatusProvider/__tests__/NetworkStatusProvider.test.tsx +4 -4
  23. package/App/ThemeManager/index.tsx +9 -0
  24. package/App/ThemeManager/utils.ts +54 -0
  25. package/App/__tests__/createQuickBrickApp.test.js +1 -1
  26. package/App/appRemoteDataLoader/index.tsx +2 -2
  27. package/App/remoteContextReloader/getRemoteContextData/getNativeRemoteContextData.ts +1 -1
  28. package/App/remoteContextReloader/helpers.ts +3 -3
  29. package/package.json +8 -8
  30. package/App/DeepLinking/URLSchemeHandler/__tests__/__snapshots__/URLSchemeHandler.test.tsx.snap +0 -24
@@ -101,26 +101,28 @@ export function usePresentSchemeHandler({
101
101
 
102
102
  // @ts-ignore - to be fixed on iOS side
103
103
  // key accountsAccountID should be accountsAccountId
104
- const accountId = getKeyFromStorage<string>(accountKey, sessionData);
104
+ const accountId = getKeyFromStorage(accountKey, sessionData);
105
105
 
106
- const appBundleIdentifier = getKeyFromStorage<string>(
106
+ const appBundleIdentifier = getKeyFromStorage(
107
107
  "bundleIdentifier",
108
108
  sessionData
109
109
  );
110
110
 
111
- const versionName = getKeyFromStorage<string>(
112
- "version_name",
113
- sessionData
114
- );
111
+ const versionName = getKeyFromStorage("version_name", sessionData);
115
112
 
116
- const familyId = getKeyFromStorage<string>(
117
- "app_family_id",
118
- sessionData
119
- );
113
+ const familyId = getKeyFromStorage("app_family_id", sessionData);
114
+
115
+ const storeKey = getKeyFromStorage("store", sessionData);
116
+
117
+ const WEB_STORE_PLATFORM: Record<string, string> = {
118
+ samsung: "samsung_app_store",
119
+ lg: "lg_content_store",
120
+ vizio: "vizio_app_store",
121
+ };
120
122
 
121
- const storeKey = getKeyFromStorage<string>("store", sessionData);
123
+ const cdnStoreKey = WEB_STORE_PLATFORM[storeKey] ?? storeKey;
122
124
 
123
- const riversUrl = `https://assets-secure.applicaster.com/zapp/accounts/${accountId}/apps/${appBundleIdentifier}/${storeKey}/${versionName}/layouts/${rivers_configuration_id}.json`;
125
+ const riversUrl = `https://assets-secure.applicaster.com/zapp/accounts/${accountId}/apps/${appBundleIdentifier}/${cdnStoreKey}/${versionName}/layouts/${rivers_configuration_id}.json`;
124
126
 
125
127
  const cellStylesUrl = `https://assets-secure.applicaster.com/zapp/accounts/${accountId}/app_families/${familyId}/layouts/${rivers_configuration_id}/cell_styles.json`;
126
128
 
@@ -1,55 +1,59 @@
1
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
2
1
  import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
3
- import * as R from "ramda";
2
+ import {
3
+ selectUrlSchemePlugins,
4
+ useAppSelector,
5
+ } from "@applicaster/zapp-react-native-redux";
4
6
 
5
7
  import { schemeHandlerHooks } from ".";
6
8
  import { parseUrl } from "../../helpers";
7
-
8
9
  import { log_warning } from "../../logger";
10
+ import { getPluginModuleUrlScheme } from "@applicaster/zapp-react-native-utils/pluginUtils";
9
11
 
10
12
  type useUrlSchemeHandlerArgs = {
11
13
  url: string;
12
14
  onFinish: (callback: (done: () => void) => void) => void;
13
15
  };
14
16
 
15
- function resolveSchemeHandler(host, plugins) {
17
+ function resolveSchemeHandler(
18
+ host: string,
19
+ eligiblePlugins: QuickBrickPlugin[]
20
+ ) {
21
+ // First check built-in scheme handlers
16
22
  if (schemeHandlerHooks?.[host]) return schemeHandlerHooks?.[host];
17
23
 
18
- const elligiblePlugins = R.filter(
19
- R.hasPath(["module", "urlScheme"]),
20
- plugins
21
- );
22
-
23
- if (elligiblePlugins?.length > 0) {
24
- const match = R.compose(
25
- R.prop("handler"),
26
- R.head,
27
- R.filter(R.propEq("host", host)),
28
- R.map(R.path(["module", "urlScheme"]))
29
- )(elligiblePlugins);
24
+ if (eligiblePlugins?.length > 0) {
25
+ // Find the first plugin with matching host
26
+ const matchingPlugin = eligiblePlugins.find(
27
+ (plugin) => getPluginModuleUrlScheme(plugin)?.host === host
28
+ );
30
29
 
31
- return match;
30
+ return getPluginModuleUrlScheme(matchingPlugin)?.handler || null;
32
31
  }
33
- }
34
32
 
35
- const skipSchemeHandle = ({ url }) => {
36
- throw new Error(
37
- `Non of the installed plugins knows how to handle this urlScheme ${url}`
38
- );
39
- };
33
+ return null;
34
+ }
40
35
 
41
36
  export function useUrlSchemeHandler({
42
37
  url,
43
38
  onFinish,
44
39
  }: useUrlSchemeHandlerArgs) {
45
40
  const { host, query } = parseUrl(url);
46
- const { plugins } = usePickFromState(["plugins"]);
41
+ const pluginsWithUrlScheme = useAppSelector(selectUrlSchemePlugins) || [];
47
42
 
48
- const useSchemeHandler =
49
- resolveSchemeHandler(host, plugins) || skipSchemeHandle;
43
+ const schemeHandler = resolveSchemeHandler(host, pluginsWithUrlScheme);
50
44
 
51
45
  try {
52
- useSchemeHandler({ query, url, onFinish });
46
+ if (schemeHandler) {
47
+ schemeHandler({ query, url, onFinish });
48
+ } else {
49
+ onFinish((done) => {
50
+ log_warning(
51
+ `unable to resolve ${url}: No handler found for scheme ${host}`
52
+ );
53
+
54
+ done?.();
55
+ });
56
+ }
53
57
  } catch (e) {
54
58
  onFinish((done) => {
55
59
  log_warning(`unable to resolve ${url}: ${e.message}`);
@@ -58,11 +62,19 @@ export function useUrlSchemeHandler({
58
62
  }
59
63
  }
60
64
 
61
- export function handleActionSchemeUrl({ url }) {
65
+ export function handleActionSchemeUrl({
66
+ url,
67
+ availablePlugins = appStore.get("plugins"),
68
+ }) {
62
69
  const { host, query } = parseUrl(url);
63
- const plugins = appStore.get("plugins");
64
70
 
65
- const actionScheme = resolveSchemeHandler(host, plugins) || skipSchemeHandle;
71
+ const actionScheme = resolveSchemeHandler(host, availablePlugins);
72
+
73
+ if (!actionScheme) {
74
+ throw new Error(
75
+ `Non of the installed plugins knows how to handle this urlScheme ${url}`
76
+ );
77
+ }
66
78
 
67
79
  actionScheme({ query, url });
68
80
  }
@@ -30,7 +30,10 @@ export function URLSchemeHandler({ url, onFinish }: Props) {
30
30
  useUrlSchemeHandler({ url, onFinish });
31
31
 
32
32
  return (
33
- <View style={[viewStyles.container, { width, height, backgroundColor }]}>
33
+ <View
34
+ testID="URLSchemeHandler"
35
+ style={[viewStyles.container, { width, height, backgroundColor }]}
36
+ >
34
37
  <Spinner size="large" />
35
38
  </View>
36
39
  );
@@ -1,5 +1,7 @@
1
1
  import React from "react";
2
- import { cleanup, render, waitFor } from "@testing-library/react-native";
2
+ import { StyleSheet } from "react-native";
3
+ import { cleanup } from "@testing-library/react-native";
4
+ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
3
5
 
4
6
  const theme = {
5
7
  screen_margin_top: 0,
@@ -10,14 +12,6 @@ jest.mock(
10
12
  "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation"
11
13
  );
12
14
 
13
- jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
14
- useTheme: jest.fn(() => theme),
15
- }));
16
-
17
- jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
18
- usePickFromState: jest.fn(() => ({})),
19
- }));
20
-
21
15
  const { URLSchemeHandler } = require("../URLSchemeHandler");
22
16
  const schemeHooks = require("../SchemeHandlerHooks/useUrlSchemeHandler");
23
17
 
@@ -36,12 +30,25 @@ describe("URLSchemeHandler", () => {
36
30
 
37
31
  afterEach(cleanup);
38
32
 
39
- it("renders correctly and invokes the hook", async () => {
40
- const wrapper = await waitFor(() =>
41
- render(<URLSchemeHandler url={url} onFinish={onFinish} />)
33
+ it("renders correctly and invokes the hook", () => {
34
+ const wrapper = renderWithProviders(
35
+ <URLSchemeHandler url={url} onFinish={onFinish} />,
36
+ {},
37
+ theme
42
38
  );
43
39
 
44
- expect(wrapper.toJSON()).toMatchSnapshot();
40
+ expect(wrapper.getByTestId("URLSchemeHandler")).toBeTruthy();
41
+
42
+ expect(
43
+ StyleSheet.flatten(wrapper.getByTestId("URLSchemeHandler").props.style)
44
+ ).toMatchObject({
45
+ alignItems: "center",
46
+ backgroundColor: "white",
47
+ flex: 1,
48
+ height: 1334,
49
+ justifyContent: "center",
50
+ width: 750,
51
+ });
45
52
 
46
53
  expect(hookSpy).toHaveBeenCalledWith(
47
54
  expect.objectContaining({ url, onFinish })
@@ -10,6 +10,7 @@ import * as ReactNative from "react-native";
10
10
 
11
11
  import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
12
12
  import { log_debug, log_error, log_info } from "../logger";
13
+ import { parseUrl } from "../helpers";
13
14
  import { getAppUrlScheme } from "@applicaster/zapp-react-native-utils/appDataUtils";
14
15
  import {
15
16
  getZappPlatform,
@@ -47,6 +48,24 @@ const getWebDeepLink = (initialURL: string) => {
47
48
  return getAppUrlScheme() + "://open" + initialURL.slice(index);
48
49
  };
49
50
 
51
+ const getPresentDeepLink = (
52
+ initialURL: string | null | undefined
53
+ ): string | null => {
54
+ if (!initialURL) return null;
55
+
56
+ const index = initialURL.indexOf("?");
57
+ if (index === -1) return null;
58
+
59
+ const { query } = parseUrl(initialURL);
60
+ if (!query?.rivers_configuration_id) return null;
61
+
62
+ return getAppUrlScheme() + "://present" + initialURL.slice(index);
63
+ };
64
+
65
+ export const triggerUrlScheme = (url: string): void => {
66
+ DeviceEventEmitter.emit("handleOpenUrl", { url });
67
+ };
68
+
50
69
  function URLSchemeContextProvider(props: Props) {
51
70
  const [state, setState] = useState<string | null>(initialState.url);
52
71
 
@@ -67,6 +86,16 @@ function URLSchemeContextProvider(props: Props) {
67
86
  const url = await Linking.getInitialURL();
68
87
 
69
88
  if (isWeb()) {
89
+ const presentDeepLink = getPresentDeepLink(url);
90
+
91
+ if (presentDeepLink) {
92
+ log_info(
93
+ `URLSchemeContextProvider: Retrieved initial deep link: ${presentDeepLink}`
94
+ );
95
+
96
+ return setState(presentDeepLink);
97
+ }
98
+
70
99
  if (getZappPlatform() === ZappPlatform.Vizio) {
71
100
  const deepLink = getWebDeepLink(url);
72
101
 
@@ -127,6 +156,36 @@ function URLSchemeContextProvider(props: Props) {
127
156
  };
128
157
  }
129
158
 
159
+ if (isWeb()) {
160
+ log_debug(
161
+ `URLSchemeContextProvider: Register DeviceEventEmitter "handleOpenUrl" listener — Platform.OS=${Platform.OS}`
162
+ );
163
+
164
+ const listener = DeviceEventEmitter.addListener(
165
+ "handleOpenUrl",
166
+ ({ url: eventUrl }) => {
167
+ if (eventUrl) {
168
+ log_info(
169
+ `URLSchemeContextProvider: DeviceEventEmitter "handleOpenUrl" received — url=${eventUrl}`
170
+ );
171
+
172
+ setState(eventUrl);
173
+ }
174
+ }
175
+ );
176
+
177
+ const linkingListener = Linking.addEventListener(
178
+ URL_EVENT_TYPE,
179
+ handleOpenURL
180
+ );
181
+
182
+ return () => {
183
+ log_debug("URLSchemeContextProvider: Remove URL event listeners");
184
+ listener.remove();
185
+ linkingListener.remove();
186
+ };
187
+ }
188
+
130
189
  log_debug("URLSchemeContextProvider: Register URL event listener");
131
190
 
132
191
  const listener = Linking.addEventListener(URL_EVENT_TYPE, handleOpenURL);
@@ -3,16 +3,15 @@ import React, { useCallback, useContext } from "react";
3
3
  import { URLSchemeHandler } from "../URLSchemeHandler";
4
4
  import { URLSchemeContext } from "./URLSchemeContextProvider";
5
5
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
6
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
+ import { useAppSelector } from "@applicaster/zapp-react-native-redux/hooks";
7
+ import { selectAppReady } from "@applicaster/zapp-react-native-redux";
7
8
 
8
9
  export function URLSchemeListener({ children }: { children: React.ReactNode }) {
9
10
  const { url, done } = useContext(URLSchemeContext);
10
11
 
11
12
  const navigator = useNavigation();
12
13
 
13
- const { appState } = usePickFromState(["appState"]);
14
-
15
- const appReady = appState?.appReady;
14
+ const appReady = useAppSelector(selectAppReady);
16
15
 
17
16
  const onFinish = useCallback(
18
17
  (callback) => {
@@ -120,13 +120,13 @@ export function isInternalUrl(url = "") {
120
120
  return query?.isInternalLink;
121
121
  }
122
122
 
123
- export function getKeyFromStorage<T extends unknown>(
123
+ export function getKeyFromStorage(
124
124
  key: keyof SessionStorageKeys,
125
125
  sessionData: Partial<SessionStorageKeys>
126
- ): T {
126
+ ): string {
127
127
  if (!sessionData[key]) {
128
128
  throw new Error(`${key} is not available in session storage data`);
129
129
  }
130
130
 
131
- return R.compose(R.replace(/"/g, ""), R.prop(key))(sessionData);
131
+ return String(sessionData[key]).replace(/"/g, "");
132
132
  }
@@ -1,4 +1,4 @@
1
- import { act, renderHook } from "@testing-library/react-hooks";
1
+ import { act, renderHook } from "@testing-library/react-native";
2
2
  import { useErrorStore } from "../store";
3
3
 
4
4
  describe("Error Store", () => {
@@ -42,12 +42,17 @@ const defaultBottomOffset = platformSelect({
42
42
  android: 0,
43
43
  });
44
44
 
45
+ const SAFE_AREA_BREAKING_API_VERSION = 35;
46
+
45
47
  const getSheetHeight = ({ height, bottomOffset, maxHeight }) => {
46
48
  return platformSelect({
47
49
  ios: height - bottomOffset,
48
50
  default:
49
51
  (height || maxHeight) -
50
- (isAndroidPlatform() && !isAndroidVersionAtLeast(35) ? bottomOffset : 0),
52
+ (isAndroidPlatform() &&
53
+ !isAndroidVersionAtLeast(SAFE_AREA_BREAKING_API_VERSION)
54
+ ? bottomOffset
55
+ : 0),
51
56
  });
52
57
  };
53
58
 
@@ -2,8 +2,9 @@ import React from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
3
 
4
4
  import { Spinner } from "@applicaster/zapp-react-native-ui-components/Components/Spinner";
5
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
+ import { useAppSelector } from "@applicaster/zapp-react-native-redux/hooks";
6
6
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
7
+ import { selectAppLaunched } from "@applicaster/zapp-react-native-redux";
7
8
 
8
9
  type Props = {
9
10
  children: React.ReactChild;
@@ -21,9 +22,7 @@ const styles = StyleSheet.create({
21
22
  });
22
23
 
23
24
  export function Loader({ children }: Props) {
24
- const {
25
- appState: { appLaunched },
26
- } = usePickFromState(["appState"]);
25
+ const appLaunched = useAppSelector(selectAppLaunched);
27
26
 
28
27
  const { currentRoute } = useNavigation();
29
28
 
@@ -7,16 +7,12 @@ import {
7
7
  getTargetRoute,
8
8
  usesVideoModal,
9
9
  } from "@applicaster/zapp-react-native-utils/navigationUtils";
10
- import { last } from "@applicaster/zapp-react-native-utils/utils";
10
+ import { clone, last } from "@applicaster/zapp-react-native-utils/utils";
11
11
  import {
12
12
  allowedOrientationsForScreen,
13
13
  useGetScreenOrientation,
14
14
  } from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
15
15
  import { focusManager } from "@applicaster/zapp-react-native-utils/focusManager/FocusManager";
16
- import {
17
- useContentTypes,
18
- usePickFromState,
19
- } from "@applicaster/zapp-react-native-redux/hooks";
20
16
 
21
17
  import reducer, {
22
18
  ACTIONS,
@@ -44,6 +40,7 @@ import {
44
40
  activeRiverSelector,
45
41
  homeRiverSelector,
46
42
  lastEntrySelector,
43
+ startUpHookPluginIdentifiersSelector,
47
44
  } from "./navigator/selectors";
48
45
 
49
46
  import { coreAppLogger } from "../logger";
@@ -79,6 +76,16 @@ import { Hook } from "@applicaster/zapp-react-native-utils/appUtils/HooksManager
79
76
  import { URLSchemeContext } from "../DeepLinking/URLSchemeListener/URLSchemeContextProvider";
80
77
 
81
78
  import { loadingOverlayManager } from "../LoadingOverlay";
79
+ import {
80
+ selectAppLaunched,
81
+ useAppSelector,
82
+ useContentTypes,
83
+ usePlugins,
84
+ } from "@applicaster/zapp-react-native-redux";
85
+ import {
86
+ useLayoutVersion,
87
+ useRivers,
88
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
82
89
 
83
90
  const logger = coreAppLogger.addSubsystem("Navigator");
84
91
 
@@ -100,22 +107,11 @@ const platform = getPlatform();
100
107
  export function NavigationProvider({ children }: Props) {
101
108
  const { url: deepLinkURL } = React.useContext(URLSchemeContext);
102
109
 
103
- const {
104
- appData: { layoutVersion },
105
- rivers,
106
- plugins,
107
- pluginConfigurations,
108
- appState: { appLaunched },
109
- } = usePickFromState([
110
- "appData",
111
- "rivers",
112
- "plugins",
113
- "pluginConfigurations",
114
- "appState",
115
- "contentTypes",
116
- ]);
117
-
110
+ const appLaunched = useAppSelector(selectAppLaunched);
111
+ const layoutVersion = useLayoutVersion();
112
+ const rivers = useRivers();
118
113
  const contentTypes = useContentTypes();
114
+ const plugins = usePlugins();
119
115
 
120
116
  const [state, dispatch] = React.useReducer<
121
117
  NavigationReducer,
@@ -227,6 +223,7 @@ export function NavigationProvider({ children }: Props) {
227
223
  };
228
224
 
229
225
  const isVideoModalDocked = () =>
226
+ state?.options.videoModal.visible &&
230
227
  state?.options.videoModal.mode === "MINIMIZED";
231
228
 
232
229
  // TODO: Remove as it's using a concept of "current" route.
@@ -249,22 +246,24 @@ export function NavigationProvider({ children }: Props) {
249
246
  const screen = rivers[screenId];
250
247
  const parent = findParent(context, navigator.currentRoute);
251
248
 
249
+ const entryClone = clone(entry);
250
+
252
251
  if (!screen) {
253
252
  logger.warn({
254
253
  message: `Cannot resolve type mapping for ${screenId} id`,
255
- data: { entry, screenId },
254
+ data: { entry: entryClone, screenId },
256
255
  });
257
256
 
258
257
  return;
259
258
  }
260
259
 
261
260
  if (parent) {
262
- entry.parent = parent?.data;
261
+ entryClone.parent = parent?.data;
263
262
 
264
- entry.parentId = parent?.id;
263
+ entryClone.parentId = parent?.id;
265
264
  }
266
265
 
267
- dispatch(setNestedContent(pathname, entry, screen));
266
+ dispatch(setNestedContent(pathname, entryClone, screen));
268
267
  };
269
268
 
270
269
  const pushItem = (item, options = {}) => {
@@ -477,21 +476,11 @@ export function NavigationProvider({ children }: Props) {
477
476
  openLoadingOverlay();
478
477
  };
479
478
 
480
- const checkStartUpHooks = React.useMemo(() => {
481
- if (!pluginConfigurations) return false;
482
-
483
- const startUpHooksIdentifiers = R.compose(
484
- R.map((item) => item.plugin.identifier),
485
- R.filter(
486
- R.allPass([
487
- R.pathEq(["plugin", "api", "require_startup_execution"], true),
488
- R.pathEq(["plugin", "react_native"], true),
489
- R.pathEq(["plugin", "preload"], true),
490
- ])
491
- ),
492
- R.values
493
- )(pluginConfigurations);
479
+ const startUpHooksIdentifiers = useAppSelector(
480
+ startUpHookPluginIdentifiersSelector
481
+ );
494
482
 
483
+ const checkStartUpHooks = React.useMemo(() => {
495
484
  if (startUpHooksIdentifiers?.length) {
496
485
  const startUpHooks = R.filter(
497
486
  (plugin) => R.includes(plugin.identifier, startUpHooksIdentifiers),
@@ -523,7 +512,7 @@ export function NavigationProvider({ children }: Props) {
523
512
  }
524
513
 
525
514
  return false;
526
- }, [pluginConfigurations, plugins, rivers]);
515
+ }, [startUpHooksIdentifiers, plugins, rivers]);
527
516
 
528
517
  const [startUpHooks, _setStartUpHooks] = React.useState(checkStartUpHooks);
529
518
  const currentStartUpHooks = React.useRef(checkStartUpHooks);
@@ -726,7 +715,7 @@ export function NavigationProvider({ children }: Props) {
726
715
  activeRiver,
727
716
  getPathname: () => pathnameRef.current, // hack use to fix issue causing broken navigation as currentRoute is unreliable
728
717
  currentRoute: pathname, // TODO: remove. Current route shouldn't be needed
729
- previousAction: lastEntrySelector(state)
718
+ previousAction: (lastEntrySelector(state) as any)
730
719
  ?.action as QuickBrickNavigationActionType,
731
720
  push: pushItem,
732
721
  replace: replaceItem,
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import * as R from "ramda";
3
3
 
4
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
4
+ import { usePlugins } from "@applicaster/zapp-react-native-redux";
5
5
 
6
6
  enum ReactHooks {
7
7
  useEffect = "useEffect",
@@ -39,7 +39,7 @@ function invokeScreenHook(hooksWrappers) {
39
39
  }
40
40
 
41
41
  export function usePluginScreenHooks(pathname: string) {
42
- const { plugins } = usePickFromState(["plugins"]);
42
+ const plugins = usePlugins();
43
43
 
44
44
  const hooks = React.useMemo(
45
45
  () => R.filter(hasScreenHook, plugins) || [],