@applicaster/quick-brick-core 12.0.0-rc.13 → 12.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 (26) hide show
  1. package/App/ActionSetters/index.ts +4 -4
  2. package/App/AssetCache/__tests__/assetCache.test.ts +1 -1
  3. package/App/AssetCache/index.ts +9 -2
  4. package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/usePresentSchemeHandler.ts +3 -5
  5. package/App/DeepLinking/URLSchemeHandler/__tests__/URLSchemeHandler.test.tsx +3 -3
  6. package/App/DeepLinking/URLSchemeListener/__tests__/URLSchemeListenerTest.js +0 -2
  7. package/App/DeepLinking/URLSchemeListener/index.tsx +3 -7
  8. package/App/LogicAggregatorContainer/index.tsx +5 -0
  9. package/App/ModalProvider/ModalBottomSheet/index.tsx +5 -1
  10. package/App/ModalProvider/ModalContent.tsx +1 -1
  11. package/App/ModalProvider/index.tsx +3 -3
  12. package/App/NavigationProvider/NavigationProvider.tsx +43 -60
  13. package/App/NavigationProvider/ScreenHooks/ApplyScreenHooks.tsx +2 -8
  14. package/App/NavigationProvider/__tests__/__snapshots__/navigationProvider.test.tsx.snap +4 -21
  15. package/App/NavigationProvider/__tests__/navigationProvider.test.tsx +137 -231
  16. package/App/NetworkStatusProvider/utils.ts +23 -1
  17. package/App/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +14 -8
  18. package/App/RouteManager/__tests__/routeManager.test.js +18 -7
  19. package/App/RouteManager/index.tsx +3 -2
  20. package/App/ThemeManager/index.tsx +1 -9
  21. package/App/__tests__/createQuickBrickApp.test.js +5 -0
  22. package/App/index.tsx +33 -26
  23. package/const/index.ts +4 -0
  24. package/createZappApp/__tests__/__snapshots__/createZappApp.test.js.snap +1 -1
  25. package/createZappApp/index.tsx +9 -2
  26. package/package.json +9 -9
@@ -88,10 +88,10 @@ const getActionInitialStateSetters = (key) => {
88
88
  return R.compose(
89
89
  R.map((subscription: { [x: string]: any; pluginId: any }) => {
90
90
  return async () => {
91
+ const now = performance.now();
92
+
91
93
  logger.info({
92
- message: `Invocation Started - action plugin ${key}, pluginId: ${
93
- subscription.pluginId
94
- }: ${performance.now()}`,
94
+ message: `Invocation Started - action plugin ${key}, pluginId: ${subscription.pluginId}`,
95
95
  });
96
96
 
97
97
  const promiseFunc = subscription[key];
@@ -101,7 +101,7 @@ const getActionInitialStateSetters = (key) => {
101
101
  logger.info({
102
102
  message: `Invocation Completed - action plugin ${key}, pluginId: ${
103
103
  subscription.pluginId
104
- }: ${performance.now()}`,
104
+ }: ${performance.now() - now} ms`,
105
105
  });
106
106
 
107
107
  return result;
@@ -323,7 +323,7 @@ describe("asset cache", () => {
323
323
 
324
324
  expect(saveCacheData).toHaveBeenCalledWith(
325
325
  layoutId,
326
- newFiles.filter(({ url }) => !url.includes("fail")),
326
+ newFiles.filter(({ url }) => !url.includes("fail"))
327
327
  );
328
328
  });
329
329
 
@@ -143,7 +143,12 @@ export async function cacheAssets({
143
143
 
144
144
  newCacheState.forEach(({ file, url }) => (urlFileMap[url] = file));
145
145
 
146
- const updatedLayout = remapAssetPath(layoutAssets, layout, urlFileMap, "layoutAssets");
146
+ const updatedLayout = remapAssetPath(
147
+ layoutAssets,
148
+ layout,
149
+ urlFileMap,
150
+ "layoutAssets"
151
+ );
147
152
 
148
153
  const updatedPluginConfigurations = remapAssetPath(
149
154
  pluginAssets,
@@ -169,6 +174,8 @@ export async function cacheAssets({
169
174
 
170
175
  return { layout, pluginConfigurations, cellStyles };
171
176
  } finally {
172
- log_verbose(`cacheAssets: caching assets took ${performance.now() - time} ms`);
177
+ log_verbose(
178
+ `cacheAssets: caching assets took ${performance.now() - time} ms`
179
+ );
173
180
  }
174
181
  }
@@ -1,7 +1,4 @@
1
- import {
2
- useActions,
3
- usePickFromState,
4
- } from "@applicaster/zapp-react-native-redux/hooks";
1
+ import { useActions } from "@applicaster/zapp-react-native-redux/hooks";
5
2
  import * as R from "ramda";
6
3
  import * as React from "react";
7
4
  import axios from "axios";
@@ -28,6 +25,7 @@ import {
28
25
  } from "../../helpers";
29
26
 
30
27
  import { log_error, log_info } from "../../logger";
28
+ import { useRivers } from "@applicaster/zapp-react-native-utils/reactHooks/state";
31
29
 
32
30
  const getFeed = (query) => ({
33
31
  content: { src: query.data_source },
@@ -60,7 +58,7 @@ export function usePresentSchemeHandler({
60
58
  feedUrl: data_source,
61
59
  });
62
60
 
63
- const { rivers } = usePickFromState(["rivers"]);
61
+ const rivers = useRivers();
64
62
  const screenRiver = findRiver({ screen_id, rivers });
65
63
  const dispatch = useDispatch();
66
64
 
@@ -1,7 +1,5 @@
1
1
  import React from "react";
2
- import { render, waitFor, cleanup } from "@testing-library/react-native";
3
-
4
- jest.mock("react-native");
2
+ import { cleanup, render, waitFor } from "@testing-library/react-native";
5
3
 
6
4
  const theme = {
7
5
  screen_margin_top: 0,
@@ -10,6 +8,8 @@ const theme = {
10
8
 
11
9
  const plugins = [];
12
10
 
11
+ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
12
+
13
13
  jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
14
14
  useTheme: jest.fn(() => theme),
15
15
  }));
@@ -7,8 +7,6 @@ import { URLSchemeListener } from "../index";
7
7
 
8
8
  const URL = "url";
9
9
 
10
- jest.mock("react-native");
11
-
12
10
  const TestComponent = () => (
13
11
  <View>
14
12
  <Text>I'm a test component</Text>
@@ -1,15 +1,11 @@
1
- import React, { ReactChild, useCallback, useContext } from "react";
1
+ import React, { useCallback, useContext } from "react";
2
2
 
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
6
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
7
7
 
8
- type Props = {
9
- children: ReactChild;
10
- };
11
-
12
- export function URLSchemeListener(props: Props) {
8
+ export function URLSchemeListener({ children }) {
13
9
  const { url, done } = useContext(URLSchemeContext);
14
10
 
15
11
  const navigator = useNavigation();
@@ -33,5 +29,5 @@ export function URLSchemeListener(props: Props) {
33
29
  return <URLSchemeHandler url={url} onFinish={onFinish} />;
34
30
  }
35
31
 
36
- return props.children;
32
+ return children;
37
33
  }
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+
3
+ export const LogicAggregatorContainer = ({ components }) => {
4
+ return components.map((Component, index) => <Component key={index} />);
5
+ };
@@ -13,6 +13,7 @@ import {
13
13
  useNavigation,
14
14
  } from "@applicaster/zapp-react-native-utils/reactHooks";
15
15
  import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
16
+ import { ModalComponent } from "@applicaster/zapp-react-native-ui-components/Components";
16
17
 
17
18
  const styles = StyleSheet.create({
18
19
  container: {
@@ -55,7 +56,10 @@ export function ModalBottomSheet(props: Props) {
55
56
  modal_bottom_sheet_tablet_max_width: sheetTabletMaxWidth,
56
57
  } = theme;
57
58
 
58
- const { ModalBottomSheetContent, modalBottomSheetContentProps } = props;
59
+ const {
60
+ ModalBottomSheetContent = ModalComponent,
61
+ modalBottomSheetContentProps,
62
+ } = props;
59
63
 
60
64
  const onLayout = useCallback(({ nativeEvent }) => {
61
65
  const calculatedHeight = nativeEvent?.layout?.height;
@@ -17,7 +17,7 @@ const styles = StyleSheet.create({
17
17
  export function ModalContent(props: Props) {
18
18
  const { modalScreenProps } = props;
19
19
 
20
- if (modalScreenProps?.screenData?.ModalBottomSheetContent) {
20
+ if (modalScreenProps?.screenData?.modalBottomSheetContentProps) {
21
21
  const { ModalBottomSheetContent, modalBottomSheetContentProps } =
22
22
  modalScreenProps?.screenData || {};
23
23
 
@@ -1,16 +1,16 @@
1
1
  import * as React from "react";
2
2
 
3
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
4
-
5
3
  import { ModalPresenter } from "./ModalPresenter";
6
4
  import { ModalContent } from "./ModalContent";
7
5
  import { ModalChildrenWrapper } from "./ModalChildrenWrapper";
8
6
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
9
7
  import { ScreenContextProvider } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenContext";
10
8
  import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
9
+ import { useModalStore } from "@applicaster/zapp-react-native-utils/modalState";
11
10
 
12
11
  export function ModalProvider() {
13
- const { modalState } = useNavigation();
12
+ const { modalState } = useModalStore();
13
+
14
14
  const [modalVisible, setModalVisible] = React.useState(false);
15
15
  const [modalShown, setModalShown] = React.useState(false);
16
16
 
@@ -63,6 +63,9 @@ import { findParent } from "@applicaster/zapp-react-native-ui-components/Context
63
63
  import { ZappPipesEntryContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
64
64
  import { PlayNextState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/OverlayObserver/OverlaysObserver";
65
65
  import { inflateUrl } from "@applicaster/zapp-react-native-ui-components/Components/LinkHandler/LinkHandler";
66
+ import { useModalStore } from "@applicaster/zapp-react-native-utils/modalState";
67
+ import { useSubscriberFor } from "@applicaster/zapp-react-native-utils/reactHooks/useSubscriberFor";
68
+ import { QBUIComponentEvents } from "@applicaster/zapp-react-native-ui-components/events";
66
69
 
67
70
  const logger = coreAppLogger.addSubsystem("Navigator");
68
71
 
@@ -92,13 +95,6 @@ const navigationActions = {
92
95
 
93
96
  const platform = getPlatform();
94
97
 
95
- const initialModalState = {
96
- visible: false,
97
- screen: null,
98
- options: {},
99
- props: {},
100
- };
101
-
102
98
  export function NavigationProvider({ children }: Props) {
103
99
  const {
104
100
  appData: { layoutVersion },
@@ -130,13 +126,16 @@ export function NavigationProvider({ children }: Props) {
130
126
  ZappPipesEntryContext.Context
131
127
  );
132
128
 
133
- const [modalState, setModalState] =
134
- React.useState<ModalState>(initialModalState);
129
+ const { openModal, dismissModal } = useModalStore();
135
130
 
136
131
  const playNextOverlayState = React.useRef();
137
132
 
138
133
  const online = useConnectionInfo(true);
139
134
 
135
+ const replaceEvent = useSubscriberFor(
136
+ QBUIComponentEvents.navigatorReplaceItem
137
+ );
138
+
140
139
  React.useEffect(() => {
141
140
  stateRef.current = state;
142
141
  pathnameRef.current = pathname;
@@ -153,6 +152,12 @@ export function NavigationProvider({ children }: Props) {
153
152
  [pathname, rivers]
154
153
  );
155
154
 
155
+ const getModalState: () => ModalState = () => {
156
+ const { modalState } = useModalStore.getState();
157
+
158
+ return modalState;
159
+ };
160
+
156
161
  const homeRiver = React.useMemo(
157
162
  () => homeRiverSelector({ rivers }),
158
163
  [rivers]
@@ -168,7 +173,7 @@ export function NavigationProvider({ children }: Props) {
168
173
  [rivers, homeRiver]
169
174
  );
170
175
 
171
- const getStack = () => [...stateRef?.current?.stack?.mainStack];
176
+ const getStack = () => [...state?.stack?.mainStack];
172
177
 
173
178
  const openVideoModal = (
174
179
  item: ZappEntry,
@@ -260,6 +265,7 @@ export function NavigationProvider({ children }: Props) {
260
265
  item?.id !==
261
266
  legacyScreenData(state?.location?.state as NavigationScreenData)?.id
262
267
  ) {
268
+ replaceEvent();
263
269
  navigateTo(item, ACTIONS.REPLACE, options);
264
270
  }
265
271
  };
@@ -276,7 +282,7 @@ export function NavigationProvider({ children }: Props) {
276
282
  route.includes(pathname)
277
283
  );
278
284
 
279
- return pathnameStackIndex > 1;
285
+ return pathnameStackIndex >= 1;
280
286
  }
281
287
 
282
288
  if (!Number.isNaN(filteredStack?.length)) {
@@ -408,9 +414,12 @@ export function NavigationProvider({ children }: Props) {
408
414
  }
409
415
  };
410
416
 
411
- const handleHookCancel = ({ hookPlugin }, dispose) => {
412
- if (hookPlugin?.lastHook) {
413
- dispose();
417
+ const handleHookCancel = ({ hookPlugin, callback }, dispose) => {
418
+ dispose();
419
+ setStartUpHooks(false);
420
+
421
+ if (callback && typeof callback === "function") {
422
+ callback();
414
423
  }
415
424
 
416
425
  if (hookPlugin.isModalHook()) {
@@ -476,7 +485,13 @@ export function NavigationProvider({ children }: Props) {
476
485
  return false;
477
486
  }, [pluginConfigurations, plugins, rivers]);
478
487
 
479
- const [startUpHooks, setStartUpHooks] = React.useState(checkStartUpHooks);
488
+ const [startUpHooks, _setStartUpHooks] = React.useState(checkStartUpHooks);
489
+ const currentStartUpHooks = React.useRef(checkStartUpHooks);
490
+
491
+ const setStartUpHooks = (value) => {
492
+ _setStartUpHooks(value);
493
+ currentStartUpHooks.current = value;
494
+ };
480
495
 
481
496
  const handleHookComplete =
482
497
  (navigationAction, targetRoute, { screen, options }) =>
@@ -484,7 +499,7 @@ export function NavigationProvider({ children }: Props) {
484
499
  if (hookPlugin?.lastHook) {
485
500
  dispose({ disposeAll: true });
486
501
 
487
- startUpHooks && setStartUpHooks(false);
502
+ startUpHooks.current && setStartUpHooks(false);
488
503
  }
489
504
 
490
505
  dispatch(
@@ -593,7 +608,10 @@ export function NavigationProvider({ children }: Props) {
593
608
  targetScreen: screen,
594
609
  rivers,
595
610
  plugins,
596
- startUpHooksData: { startUpHooks, setStartUpHooks },
611
+ startUpHooksData: {
612
+ startUpHooks: currentStartUpHooks.current,
613
+ setStartUpHooks,
614
+ },
597
615
  };
598
616
 
599
617
  HooksManager(hooksOptions)
@@ -615,31 +633,6 @@ export function NavigationProvider({ children }: Props) {
615
633
  },
616
634
  });
617
635
 
618
- const openModal = React.useCallback(
619
- ({ item, options = {}, props = {} }: OpenModalArg) => {
620
- setModalState({
621
- visible: true,
622
- screen: item as ZappRiver,
623
- options: {
624
- animated: true,
625
- animationType: "slide",
626
- onShow: () => {},
627
- presentationStyle: "overFullScreen",
628
- transparent: true,
629
- ...options,
630
- onDismiss: () => {
631
- setModalState(initialModalState);
632
- },
633
- onRequestClose: () => {
634
- dismissModal();
635
- },
636
- },
637
- props,
638
- });
639
- },
640
- []
641
- );
642
-
643
636
  const openPiP = React.useCallback(() => {
644
637
  dispatch(setVideoPiP());
645
638
  }, []);
@@ -660,10 +653,6 @@ export function NavigationProvider({ children }: Props) {
660
653
  }
661
654
  }, [state?.options?.videoModal?.previousMode]);
662
655
 
663
- const dismissModal = React.useCallback(() => {
664
- setModalState(() => ({ ...initialModalState }));
665
- }, []);
666
-
667
656
  const openModalBottomSheet = React.useCallback(
668
657
  ({
669
658
  ModalBottomSheetContent,
@@ -695,15 +684,15 @@ export function NavigationProvider({ children }: Props) {
695
684
 
696
685
  // It will only work for the regular stack and pathname, It won't work for modals
697
686
  // TODO: integrate video/hook and regular modal into stack.
698
- const getStackForPathname = React.useCallback((pathname: string):
699
- | NavigationScreenState
700
- | undefined => {
701
- const stack = getStack();
687
+ const getStackForPathname = (
688
+ pathname: string
689
+ ): NavigationScreenState | undefined => {
690
+ const stack = [...state?.stack?.mainStack];
702
691
 
703
692
  const currentStack = stack.find(({ route }) => route === pathname);
704
693
 
705
694
  return currentStack;
706
- }, []);
695
+ };
707
696
 
708
697
  const navigator: QuickBrickAppNavigator = React.useMemo(
709
698
  () => ({
@@ -730,7 +719,7 @@ export function NavigationProvider({ children }: Props) {
730
719
  modalData: state.stack.modal?.state ?? null,
731
720
  openModal,
732
721
  dismissModal,
733
- modalState,
722
+ getModalState,
734
723
  openModalBottomSheet,
735
724
  closeModalBottomSheet,
736
725
  videoModalState: state.options.videoModal,
@@ -747,15 +736,9 @@ export function NavigationProvider({ children }: Props) {
747
736
  replaceTop,
748
737
  getStack,
749
738
  getStackForPathname,
739
+ mainStack: state.stack.mainStack,
750
740
  }),
751
- [
752
- rivers,
753
- plugins,
754
- JSON.stringify(state),
755
- modalState,
756
- appLaunched,
757
- startUpHooks,
758
- ]
741
+ [rivers, plugins, JSON.stringify(state), appLaunched, startUpHooks]
759
742
  );
760
743
 
761
744
  // when running the tests, we pass the dispatch function
@@ -1,15 +1,9 @@
1
1
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
2
- import * as React from "react";
3
2
  import { usePluginScreenHooks } from "./usePluginScreenHooks";
4
3
 
5
- type Props = {
6
- pathname: string;
7
- children: React.ReactChildren;
8
- };
9
-
10
- export function ApplyScreenHooks({ children }: Props) {
4
+ export function ApplyScreenHooks() {
11
5
  const { currentRoute } = useNavigation();
12
6
  usePluginScreenHooks(currentRoute);
13
7
 
14
- return children;
8
+ return null;
15
9
  }
@@ -11,7 +11,9 @@ Object {
11
11
  "presentationStyle": "overFullScreen",
12
12
  "transparent": true,
13
13
  },
14
- "props": Object {},
14
+ "props": Object {
15
+ "screenData": Object {},
16
+ },
15
17
  "screen": Object {
16
18
  "id": "A1234",
17
19
  "navigations": Array [],
@@ -30,26 +32,7 @@ Object {
30
32
  }
31
33
  `;
32
34
 
33
- exports[`<NavigationProvider /> modal feature sets the modalState when opening a modal 1`] = `
34
- Object {
35
- "options": Object {
36
- "animated": true,
37
- "animationType": "slide",
38
- "onDismiss": [Function],
39
- "onRequestClose": [Function],
40
- "onShow": [Function],
41
- "presentationStyle": "overFullScreen",
42
- "transparent": true,
43
- },
44
- "props": Object {},
45
- "screen": Object {
46
- "id": "A1234",
47
- "navigations": Array [],
48
- "ui_components": Array [],
49
- },
50
- "visible": true,
51
- }
52
- `;
35
+ exports[`<NavigationProvider /> modal feature sets the modalState when opening a modal 1`] = `undefined`;
53
36
 
54
37
  exports[`<NavigationProvider /> modal feature should reset state to initial when dismissing a modal ( closeModalBottomSheet ) opened by openModalBottomSheet 1`] = `
55
38
  Object {