@applicaster/quick-brick-core 14.0.0-alpha.3038031102 → 14.0.0-alpha.3140225604
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.
- package/App/ActionSetters/index.ts +0 -1
- package/App/ActionsProvider/index.js +1 -1
- package/App/AppStateDecorator/index.tsx +2 -2
- package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/usePresentSchemeHandler.test.tsx +17 -13
- package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/useOpenSchemeHandler/index.ts +2 -7
- package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/usePresentSchemeHandler.ts +4 -6
- package/App/DeepLinking/URLSchemeHandler/__tests__/URLSchemeHandler.test.tsx +4 -4
- package/App/ErrorBoundary/index.tsx +4 -0
- package/App/ModalProvider/ModalBottomSheet/ModalBottomSheetFrame.tsx +1 -1
- package/App/NavigationProvider/navigator/selectors.ts +1 -2
- package/App/StoreConnector/index.ts +1 -1
- package/App/ThemeManager/index.tsx +9 -1
- package/App/appLifeCycleManager/__tests__/appLifeCycleManager.test.tsx +25 -20
- package/App/appLifeCycleManager/index.tsx +6 -5
- package/App/remoteContextReloader/__tests__/getRemoteContextData.test.js +12 -11
- package/App/remoteContextReloader/getRemoteContextData/getNativeRemoteContextData.ts +3 -5
- package/README.md +4 -0
- package/createZappApp/index.tsx +5 -4
- package/package.json +9 -14
- package/renderZappApp/index.js +2 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
|
-
import { connectToStore } from "@applicaster/zapp-react-native-redux
|
|
4
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
5
5
|
|
|
6
6
|
import { ActionsProvider as ActionsProviderComponent } from "./ActionsProvider";
|
|
7
7
|
|
|
@@ -2,9 +2,9 @@ import * as React from "react";
|
|
|
2
2
|
import { AppState, AppStateStatus } from "react-native";
|
|
3
3
|
import * as R from "ramda";
|
|
4
4
|
|
|
5
|
-
import { connectToStore } from "@applicaster/zapp-react-native-redux
|
|
5
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
6
6
|
import { setAppState } from "@applicaster/zapp-react-native-redux/appState";
|
|
7
|
-
import { Dispatch } from "
|
|
7
|
+
import { Dispatch } from "redux";
|
|
8
8
|
|
|
9
9
|
type Props = {
|
|
10
10
|
Component: () => React.ComponentType<any>;
|
|
@@ -3,9 +3,10 @@ import * as R from "ramda";
|
|
|
3
3
|
import axios from "axios";
|
|
4
4
|
import { renderHook } from "@testing-library/react-hooks";
|
|
5
5
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
6
|
-
|
|
6
|
+
import * as zappRedux from "@applicaster/zapp-react-native-redux";
|
|
7
7
|
import * as helpers from "../../../helpers";
|
|
8
8
|
import * as feedLoader from "@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedLoader";
|
|
9
|
+
import * as useNavigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
|
|
9
10
|
|
|
10
11
|
import { Provider } from "react-redux";
|
|
11
12
|
import configureStore from "redux-mock-store";
|
|
@@ -16,24 +17,19 @@ const rivers = {
|
|
|
16
17
|
},
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
const
|
|
20
|
+
const navigator = {
|
|
20
21
|
currentRoute: "/river/A1234",
|
|
21
22
|
replace: jest.fn(),
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
jest.mock(
|
|
25
|
-
"@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation",
|
|
26
|
-
() => ({
|
|
27
|
-
useNavigation: jest.fn(() => mock_navigator),
|
|
28
|
-
})
|
|
29
|
-
);
|
|
30
|
-
|
|
31
25
|
const mockStore = configureStore();
|
|
32
26
|
|
|
27
|
+
jest
|
|
28
|
+
.spyOn(useNavigationHooks, "useNavigation")
|
|
29
|
+
.mockImplementation(() => navigator);
|
|
30
|
+
|
|
33
31
|
const helperSpy = jest.spyOn(helpers, "handlePresentNavigation");
|
|
34
32
|
const feedLoaderSpy = jest.spyOn(feedLoader, "useFeedLoader");
|
|
35
|
-
const storageSpy = jest.spyOn(sessionStorage, "getAllItems");
|
|
36
|
-
const axiosGetSpy = jest.spyOn(axios, "get");
|
|
37
33
|
|
|
38
34
|
const { usePresentSchemeHandler } = require("../usePresentSchemeHandler");
|
|
39
35
|
|
|
@@ -41,8 +37,6 @@ const onFinish = jest.fn((cb) => {
|
|
|
41
37
|
cb();
|
|
42
38
|
});
|
|
43
39
|
|
|
44
|
-
const navigator = mock_navigator;
|
|
45
|
-
|
|
46
40
|
describe("usePresentSchemeHandler", () => {
|
|
47
41
|
beforeEach(() => {
|
|
48
42
|
onFinish.mockClear();
|
|
@@ -194,6 +188,10 @@ describe("usePresentSchemeHandler", () => {
|
|
|
194
188
|
rivers_configuration_id: "test",
|
|
195
189
|
};
|
|
196
190
|
|
|
191
|
+
const storageSpy = jest.spyOn(sessionStorage, "getAllItems");
|
|
192
|
+
const axiosGetSpy = jest.spyOn(axios, "get");
|
|
193
|
+
const zappReduxSpy = jest.spyOn(zappRedux, "loadAppContextData");
|
|
194
|
+
|
|
197
195
|
const getAllItems = jest.fn().mockResolvedValue({
|
|
198
196
|
accountsAccountId: "accountsAccountId",
|
|
199
197
|
bundleIdentifier: "bundleIdentifier",
|
|
@@ -206,6 +204,7 @@ describe("usePresentSchemeHandler", () => {
|
|
|
206
204
|
|
|
207
205
|
storageSpy.mockImplementation(getAllItems);
|
|
208
206
|
axiosGetSpy.mockImplementation(get);
|
|
207
|
+
zappReduxSpy.mockReturnValue(null);
|
|
209
208
|
|
|
210
209
|
renderHook(() => usePresentSchemeHandler({ query, url: "", onFinish }), {
|
|
211
210
|
wrapper,
|
|
@@ -220,6 +219,11 @@ describe("usePresentSchemeHandler", () => {
|
|
|
220
219
|
|
|
221
220
|
expect(actions?.find(R.propEq("type", "SET_APP_READY"))).toBeDefined();
|
|
222
221
|
|
|
222
|
+
expect(zappReduxSpy).toBeCalledWith(expect.any(Function), {
|
|
223
|
+
cellStyles: "url",
|
|
224
|
+
rivers: "url",
|
|
225
|
+
});
|
|
226
|
+
|
|
223
227
|
expect(navigator.replace).toBeCalledWith({});
|
|
224
228
|
};
|
|
225
229
|
});
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useAppSelector,
|
|
3
|
-
selectContentTypes,
|
|
4
|
-
selectRivers,
|
|
5
|
-
} from "@applicaster/zapp-react-native-redux";
|
|
1
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
6
2
|
import { ZappPipesEntryContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
|
|
7
3
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
8
4
|
import { useEffect } from "react";
|
|
@@ -101,8 +97,7 @@ async function handleQuery({
|
|
|
101
97
|
}
|
|
102
98
|
|
|
103
99
|
export function useOpenSchemeHandler({ query, url, onFinish }) {
|
|
104
|
-
const rivers =
|
|
105
|
-
const contentTypes = useAppSelector(selectContentTypes);
|
|
100
|
+
const { rivers, contentTypes } = usePickFromState(["rivers", "contentTypes"]);
|
|
106
101
|
const navigator = useNavigation();
|
|
107
102
|
const homeId = getHomeScreenId(rivers);
|
|
108
103
|
const homeRoute = `/river/${homeId}`;
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadAppContextData,
|
|
3
|
-
useAppDispatch,
|
|
4
|
-
useActions,
|
|
5
|
-
} from "@applicaster/zapp-react-native-redux";
|
|
1
|
+
import { useActions } from "@applicaster/zapp-react-native-redux/hooks";
|
|
6
2
|
import * as R from "ramda";
|
|
7
3
|
import * as React from "react";
|
|
8
4
|
import axios from "axios";
|
|
5
|
+
import { useDispatch } from "react-redux";
|
|
9
6
|
|
|
10
7
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
11
8
|
|
|
12
9
|
import { useFeedLoader } from "@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedLoader";
|
|
13
10
|
|
|
14
11
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
12
|
+
import { loadAppContextData } from "@applicaster/zapp-react-native-redux";
|
|
15
13
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
16
14
|
|
|
17
15
|
import {
|
|
@@ -62,7 +60,7 @@ export function usePresentSchemeHandler({
|
|
|
62
60
|
|
|
63
61
|
const rivers = useRivers();
|
|
64
62
|
const screenRiver = findRiver({ screen_id, rivers });
|
|
65
|
-
const dispatch =
|
|
63
|
+
const dispatch = useDispatch();
|
|
66
64
|
|
|
67
65
|
const actions = useActions({
|
|
68
66
|
setAppReady,
|
|
@@ -6,16 +6,16 @@ const theme = {
|
|
|
6
6
|
app_background_color: "white",
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
);
|
|
9
|
+
const plugins = [];
|
|
10
|
+
|
|
11
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
|
|
12
12
|
|
|
13
13
|
jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
|
|
14
14
|
useTheme: jest.fn(() => theme),
|
|
15
15
|
}));
|
|
16
16
|
|
|
17
17
|
jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
|
|
18
|
-
usePickFromState: jest.fn(() =>
|
|
18
|
+
usePickFromState: jest.fn(() => plugins),
|
|
19
19
|
}));
|
|
20
20
|
|
|
21
21
|
const { URLSchemeHandler } = require("../URLSchemeHandler");
|
|
@@ -60,6 +60,10 @@ export class ErrorBoundary extends React.Component<Props> {
|
|
|
60
60
|
useErrorStore.getState().setError(error, info, recoverable);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
getDerivedStateFromError(_error) {
|
|
64
|
+
return { hasError: true };
|
|
65
|
+
}
|
|
66
|
+
|
|
63
67
|
render() {
|
|
64
68
|
return <ErrorBoundaryContent>{this.props.children}</ErrorBoundaryContent>;
|
|
65
69
|
}
|
|
@@ -47,7 +47,7 @@ const getSheetHeight = ({ height, bottomOffset, maxHeight }) => {
|
|
|
47
47
|
ios: height - bottomOffset,
|
|
48
48
|
default:
|
|
49
49
|
(height || maxHeight) -
|
|
50
|
-
(
|
|
50
|
+
(isAndroidPlatform() && !isAndroidVersionAtLeast(35) ? bottomOffset : 0),
|
|
51
51
|
});
|
|
52
52
|
};
|
|
53
53
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
|
-
import { createSelector } from "
|
|
2
|
+
import { createSelector } from "reselect";
|
|
3
3
|
|
|
4
4
|
import { getPathAttributes } from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
5
5
|
|
|
@@ -7,7 +7,6 @@ const riverSelector = R.prop("rivers");
|
|
|
7
7
|
const pathnameSelector = R.prop("pathname");
|
|
8
8
|
const navigationStackSelector = R.prop("stack");
|
|
9
9
|
|
|
10
|
-
// @TODO extract to zapp-react-native-redux/selectors, remove ramda
|
|
11
10
|
export const homeRiverSelector = createSelector(
|
|
12
11
|
riverSelector,
|
|
13
12
|
R.compose(R.find(R.propEq("home", true)), R.values)
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
mapKeys,
|
|
9
9
|
partitionByKeys,
|
|
10
10
|
} from "@applicaster/zapp-react-native-utils/objectUtils";
|
|
11
|
+
import { getLocalizations } from "@applicaster/zapp-react-native-utils/appUtils/localizationsHelper";
|
|
11
12
|
|
|
12
13
|
type Props = {
|
|
13
14
|
children: React.ReactNode;
|
|
@@ -23,7 +24,14 @@ function populateTheme(plugin) {
|
|
|
23
24
|
return null;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
const themeLocalizations =
|
|
28
|
+
getLocalizations({
|
|
29
|
+
localizations: plugin?.configuration?.localizations,
|
|
30
|
+
}) || {};
|
|
31
|
+
|
|
32
|
+
const themeProps = getProps(plugin?.configuration || {});
|
|
33
|
+
|
|
34
|
+
return [id, { ...themeProps, ...themeLocalizations }];
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
const TABLET_PREFIX = "tablet_";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View, Text } from "react-native";
|
|
3
|
-
import { waitFor } from "@testing-library/react-native";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
3
|
+
import { render, waitFor } from "@testing-library/react-native";
|
|
4
|
+
import thunk from "redux-thunk";
|
|
5
|
+
import configureStore from "redux-mock-store";
|
|
6
6
|
|
|
7
7
|
let mocked_items: Record<string, any> = {};
|
|
8
8
|
|
|
@@ -10,11 +10,8 @@ import { appLifeCycleManager } from "../";
|
|
|
10
10
|
|
|
11
11
|
const mock_actions = {};
|
|
12
12
|
|
|
13
|
-
jest.mock("@applicaster/zapp-react-native-redux", () => ({
|
|
14
|
-
|
|
15
|
-
AppData: {
|
|
16
|
-
loadAppData: jest.fn(() => () => Promise.resolve()),
|
|
17
|
-
},
|
|
13
|
+
jest.mock("@applicaster/zapp-react-native-redux/AppData", () => ({
|
|
14
|
+
loadAppData: jest.fn(() => () => Promise.resolve()),
|
|
18
15
|
}));
|
|
19
16
|
|
|
20
17
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/actions", () => ({
|
|
@@ -25,9 +22,6 @@ jest.mock(
|
|
|
25
22
|
"@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage",
|
|
26
23
|
() => ({
|
|
27
24
|
localStorage: {
|
|
28
|
-
...jest.requireActual(
|
|
29
|
-
"@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage"
|
|
30
|
-
).localStorage,
|
|
31
25
|
getAllItems: jest.fn(() => Promise.resolve(mocked_items)),
|
|
32
26
|
setItem: jest.fn((key, value) => {
|
|
33
27
|
mocked_items[key] = JSON.stringify(value);
|
|
@@ -70,8 +64,12 @@ const appLoader = jest.fn((_dispatch, _getState) => {
|
|
|
70
64
|
return Promise.resolve();
|
|
71
65
|
});
|
|
72
66
|
|
|
67
|
+
const store = configureStore([thunk])({});
|
|
68
|
+
const dispatch = store.dispatch;
|
|
69
|
+
|
|
73
70
|
const state = {
|
|
74
|
-
|
|
71
|
+
rivers: {},
|
|
72
|
+
plugins: {},
|
|
75
73
|
appSettings: { runtimeConfigurationUrls: { rivers: "http://rivers.url" } },
|
|
76
74
|
};
|
|
77
75
|
|
|
@@ -93,16 +91,19 @@ describe("appLifeCycleManager", () => {
|
|
|
93
91
|
it("runs the loaders, then sends quickBrickReady event", async () => {
|
|
94
92
|
const testCallback = jest.fn(() => {});
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
<DecoratedComponent
|
|
98
|
-
|
|
94
|
+
render(
|
|
95
|
+
<DecoratedComponent
|
|
96
|
+
dispatch={dispatch}
|
|
97
|
+
{...state}
|
|
98
|
+
testCallback={testCallback}
|
|
99
|
+
/>
|
|
99
100
|
);
|
|
100
101
|
|
|
101
102
|
await waitFor(() => {
|
|
102
103
|
return expect(testCallback).toHaveBeenCalled();
|
|
103
104
|
});
|
|
104
105
|
|
|
105
|
-
const actions =
|
|
106
|
+
const actions = store.getActions();
|
|
106
107
|
|
|
107
108
|
expect(actions[0]).toMatchObject({ type: "SET_APP_READY" });
|
|
108
109
|
|
|
@@ -116,12 +117,16 @@ describe("appLifeCycleManager", () => {
|
|
|
116
117
|
it("sends the quickBrickReady event when a loader doesn't resolves", async () => {
|
|
117
118
|
const testCallback = jest.fn(() => {});
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
<DecoratedComponent
|
|
121
|
-
|
|
120
|
+
render(
|
|
121
|
+
<DecoratedComponent
|
|
122
|
+
dispatch={dispatch}
|
|
123
|
+
{...state}
|
|
124
|
+
shouldFail
|
|
125
|
+
testCallback={testCallback}
|
|
126
|
+
/>
|
|
122
127
|
);
|
|
123
128
|
|
|
124
|
-
const actions =
|
|
129
|
+
const actions = store.getActions();
|
|
125
130
|
|
|
126
131
|
await waitFor(() => {
|
|
127
132
|
return expect(testCallback).toHaveBeenCalled();
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
4
|
import { sendLaunchEvent } from "@applicaster/zapp-react-native-utils/analyticsUtils";
|
|
5
|
-
import {
|
|
5
|
+
import { loadAppData } from "@applicaster/zapp-react-native-redux/AppData";
|
|
6
6
|
import {
|
|
7
7
|
setAppLaunched,
|
|
8
8
|
setAppReady,
|
|
@@ -13,6 +13,7 @@ import { networkStatusReady } from "../NetworkStatusProvider/networkStatusReady"
|
|
|
13
13
|
import { updateSessionNumber } from "../SessionCounter/sessionCounter";
|
|
14
14
|
|
|
15
15
|
import { coreAppLogger } from "../logger";
|
|
16
|
+
import { Dispatch } from "@reduxjs/toolkit";
|
|
16
17
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
17
18
|
import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
18
19
|
import { requiredSessionKeys } from "../../const";
|
|
@@ -23,6 +24,7 @@ const logger = coreAppLogger.addSubsystem("AppLifeCycleManager");
|
|
|
23
24
|
const isAndroid = isAndroidPlatform();
|
|
24
25
|
|
|
25
26
|
type Props = {
|
|
27
|
+
dispatch: Dispatch;
|
|
26
28
|
testCallback: () => void;
|
|
27
29
|
plugins: QuickBrickPlugin[];
|
|
28
30
|
appSettings: { runtimeConfigurationUrls: { [key in string]: string } };
|
|
@@ -33,7 +35,6 @@ export function appLifeCycleManager(appLoader, QuickBrickManager) {
|
|
|
33
35
|
// this function is not called until React View is mounted to activity(ie quickBrickReady event sent)
|
|
34
36
|
return function AppLifeCycleManagerRenderer(props: Props) {
|
|
35
37
|
const actionsInitialStateSetters = useActionSetters();
|
|
36
|
-
const dispatch = useAppDispatch();
|
|
37
38
|
// using useLayoutEffect to call the loader just after the DOM render to mimic componentDidMount timing
|
|
38
39
|
|
|
39
40
|
async function setUpdateSessionNumber(results: unknown[]) {
|
|
@@ -92,7 +93,7 @@ export function appLifeCycleManager(appLoader, QuickBrickManager) {
|
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
function makeAppReady() {
|
|
95
|
-
const { testCallback } = props;
|
|
96
|
+
const { dispatch, testCallback } = props;
|
|
96
97
|
|
|
97
98
|
dispatch(setAppReady());
|
|
98
99
|
dispatch(setAppLaunched());
|
|
@@ -152,14 +153,14 @@ export function appLifeCycleManager(appLoader, QuickBrickManager) {
|
|
|
152
153
|
|
|
153
154
|
const prepareApp = async () => {
|
|
154
155
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
155
|
-
const { testCallback, ...state } = props;
|
|
156
|
+
const { dispatch, testCallback, ...state } = props;
|
|
156
157
|
|
|
157
158
|
try {
|
|
158
159
|
const getState = () => state;
|
|
159
160
|
|
|
160
161
|
const loaders = [
|
|
161
162
|
appLoader(dispatch, getState),
|
|
162
|
-
dispatch<any>(
|
|
163
|
+
dispatch<any>(loadAppData()),
|
|
163
164
|
networkStatusReady(),
|
|
164
165
|
];
|
|
165
166
|
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
+
import * as ReduxModule from "@applicaster/zapp-react-native-redux";
|
|
1
2
|
import nock from "nock";
|
|
2
3
|
|
|
3
4
|
jest.mock("../../AssetCache", () => ({
|
|
4
5
|
cacheAssets: jest.fn((x) => x),
|
|
5
6
|
}));
|
|
6
7
|
|
|
7
|
-
const mockLoadAppContextData = jest.fn(() => ({}));
|
|
8
|
-
|
|
9
|
-
jest.mock("@applicaster/zapp-react-native-redux", () => ({
|
|
10
|
-
...jest.requireActual("@applicaster/zapp-react-native-redux"),
|
|
11
|
-
loadAppContextData: mockLoadAppContextData,
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
8
|
const uuid = "342ee911-03b6-4a16-adde-ece5ef739feb";
|
|
15
9
|
|
|
16
10
|
const { getRemoteContextData } = require("../getRemoteContextData");
|
|
@@ -106,12 +100,11 @@ const failingRuntimeConfigurationUrls = {
|
|
|
106
100
|
remote_configurations_url: "http://zapp.com/failing.json",
|
|
107
101
|
};
|
|
108
102
|
|
|
103
|
+
let reduxLoaderSpy;
|
|
109
104
|
const dispatch = jest.fn();
|
|
110
105
|
|
|
111
106
|
describe("getRemoteContextData", () => {
|
|
112
107
|
beforeEach(() => {
|
|
113
|
-
mockLoadAppContextData.mockClear();
|
|
114
|
-
|
|
115
108
|
nock("http://zapp.com").persist().get("/layout.json").reply(200, layout);
|
|
116
109
|
|
|
117
110
|
nock("http://zapp.com")
|
|
@@ -127,12 +120,20 @@ describe("getRemoteContextData", () => {
|
|
|
127
120
|
nock("http://zapp.com")
|
|
128
121
|
.get("/failing.json")
|
|
129
122
|
.reply(Math.floor(Math.random() * 200 + 400), 0);
|
|
123
|
+
|
|
124
|
+
reduxLoaderSpy = jest
|
|
125
|
+
.spyOn(ReduxModule, "loadAppContextData")
|
|
126
|
+
.mockImplementation(() => ({}));
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
afterEach(() => {
|
|
130
|
+
reduxLoaderSpy.mockRestore();
|
|
130
131
|
});
|
|
131
132
|
|
|
132
133
|
it("returns a map of context data with the result of the matched urls", async () => {
|
|
133
134
|
await getRemoteContextData(dispatch, runtimeConfigurationUrls, plugins);
|
|
134
135
|
|
|
135
|
-
return expect(
|
|
136
|
+
return expect(reduxLoaderSpy).toHaveBeenCalledWith(
|
|
136
137
|
dispatch,
|
|
137
138
|
expect.objectContaining({
|
|
138
139
|
pluginConfigurations,
|
|
@@ -146,7 +147,7 @@ describe("getRemoteContextData", () => {
|
|
|
146
147
|
});
|
|
147
148
|
|
|
148
149
|
it("skips the context data if it cannot be retrieved", async () => {
|
|
149
|
-
expect(
|
|
150
|
+
expect(reduxLoaderSpy).not.toHaveBeenCalled();
|
|
150
151
|
|
|
151
152
|
return expect(
|
|
152
153
|
getRemoteContextData(dispatch, failingRuntimeConfigurationUrls, plugins)
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
2
|
import isEmpty from "lodash/isEmpty";
|
|
3
3
|
import { Dimensions, NativeModules } from "react-native";
|
|
4
|
-
import {
|
|
5
|
-
loadAppContextData,
|
|
6
|
-
AppData,
|
|
7
|
-
} from "@applicaster/zapp-react-native-redux";
|
|
4
|
+
import { loadAppContextData } from "@applicaster/zapp-react-native-redux";
|
|
8
5
|
import { isTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
9
6
|
import { mapPromises } from "@applicaster/zapp-react-native-utils/arrayUtils";
|
|
10
7
|
import { fetchPluginConfiguration, getPromiseForType } from "../helpers";
|
|
11
8
|
import { cacheAssets } from "../../AssetCache";
|
|
9
|
+
import { actions as appDataActions } from "@applicaster/zapp-react-native-redux/AppData";
|
|
12
10
|
import { logger } from "@applicaster/zapp-react-native-utils/logger";
|
|
13
11
|
import { ACTIVE_LAYOUT_ID_STORAGE_KEY } from "../consts";
|
|
14
12
|
const { AppLoaderBridge } = NativeModules;
|
|
@@ -76,7 +74,7 @@ export async function getNativeRemoteContextData(
|
|
|
76
74
|
|
|
77
75
|
const apiVersion = layout?.layout?.["api_version"]; // Taken from remote configuration
|
|
78
76
|
|
|
79
|
-
dispatch(
|
|
77
|
+
dispatch(appDataActions.merge({ layoutVersion: apiVersion || "v1" }));
|
|
80
78
|
|
|
81
79
|
const resolvedPromises = await mapPromises(getPromiseForType, ["cellStyles"]);
|
|
82
80
|
|
package/README.md
CHANGED
|
@@ -42,6 +42,10 @@ Creates a Zapp App with the provided options :
|
|
|
42
42
|
- `module`: the plugin's callable function / React component
|
|
43
43
|
- `name`: the name of the plugin - should match the `PascalCase`'d identifier of the plugin. If your plugin's identifier is `react-native-article`, the name should be `ReactNativeArticle`
|
|
44
44
|
- `type`: the type of the plugin, as it is defined in the plugin's manifest in Zapp
|
|
45
|
+
- `reduxStoreOptions`: (optional)
|
|
46
|
+
- `additionalReducers`: map of reducers to load in the redux store, on top of the existing ones. See available reducers' names to avoid name collision which would override your own custom reducers
|
|
47
|
+
- `additionalMiddlewares`: array of additional middlewares to load - by default, the ZappApp will have the `thunk` middleware, but others can be added
|
|
48
|
+
- `initialState`: optional initial state for the redux store
|
|
45
49
|
- `pluginConfigurations`: the remote configuration options for plugins, as coming from Zapp
|
|
46
50
|
- `remoteConfigurations`: Zapp's remote configurations
|
|
47
51
|
- `appSettings`: arbitrary app settings which will be stored in the redux store.
|
package/createZappApp/index.tsx
CHANGED
|
@@ -12,10 +12,9 @@ import {
|
|
|
12
12
|
isNotNil,
|
|
13
13
|
} from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
|
|
14
14
|
|
|
15
|
-
import { createZappReduxStore } from "@applicaster/zapp-react-native-redux/utils/createZappReduxStore";
|
|
16
15
|
import {
|
|
16
|
+
createZappReduxStore,
|
|
17
17
|
loadAppContextData,
|
|
18
|
-
AppData,
|
|
19
18
|
} from "@applicaster/zapp-react-native-redux";
|
|
20
19
|
|
|
21
20
|
import { coreLogger } from "@applicaster/zapp-react-native-utils/logger";
|
|
@@ -27,6 +26,7 @@ import { Provider } from "react-redux";
|
|
|
27
26
|
import { EmptyZappApp } from "../defaults";
|
|
28
27
|
import { mergeUiComponentPlugins } from "../helpers";
|
|
29
28
|
import { isTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
29
|
+
import { actions as appDataActions } from "@applicaster/zapp-react-native-redux/AppData";
|
|
30
30
|
import { remoteDataLoader } from "../App/appRemoteDataLoader/remoteDataLoader";
|
|
31
31
|
import * as QuickBrickManager from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
32
32
|
import { isAndroidPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
@@ -51,6 +51,7 @@ export function createZappApp(zappAppConfig: ZappAppConfig) {
|
|
|
51
51
|
remoteConfigurations = {},
|
|
52
52
|
layout = {},
|
|
53
53
|
tabletLayout = {},
|
|
54
|
+
reduxStoreOptions = {},
|
|
54
55
|
appSettings = {},
|
|
55
56
|
ZappApp = EmptyZappApp,
|
|
56
57
|
presetsMapping = {},
|
|
@@ -88,7 +89,7 @@ export function createZappApp(zappAppConfig: ZappAppConfig) {
|
|
|
88
89
|
injectCorePlugins
|
|
89
90
|
)(plugins);
|
|
90
91
|
|
|
91
|
-
const store = createZappReduxStore();
|
|
92
|
+
const store = createZappReduxStore(reduxStoreOptions);
|
|
92
93
|
|
|
93
94
|
const appComponents = mergeUiComponentPlugins(components, plugins);
|
|
94
95
|
|
|
@@ -112,7 +113,7 @@ export function createZappApp(zappAppConfig: ZappAppConfig) {
|
|
|
112
113
|
// Handle case when layout is backed in as part of the environment, dev only
|
|
113
114
|
// TODO: Handle it inside getNativeRemoteContextData
|
|
114
115
|
store.dispatch(
|
|
115
|
-
|
|
116
|
+
appDataActions.merge({
|
|
116
117
|
layoutVersion: layout?.api_version ? layout.api_version : "v1",
|
|
117
118
|
})
|
|
118
119
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-core",
|
|
3
|
-
"version": "14.0.0-alpha.
|
|
3
|
+
"version": "14.0.0-alpha.3140225604",
|
|
4
4
|
"description": "Core package for Applicaster's Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,13 +28,13 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "14.0.0-alpha.
|
|
32
|
-
"@applicaster/quick-brick-core-plugins": "14.0.0-alpha.
|
|
33
|
-
"@applicaster/zapp-pipes-v2-client": "14.0.0-alpha.
|
|
34
|
-
"@applicaster/zapp-react-native-bridge": "14.0.0-alpha.
|
|
35
|
-
"@applicaster/zapp-react-native-redux": "14.0.0-alpha.
|
|
36
|
-
"@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.
|
|
37
|
-
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "14.0.0-alpha.3140225604",
|
|
32
|
+
"@applicaster/quick-brick-core-plugins": "14.0.0-alpha.3140225604",
|
|
33
|
+
"@applicaster/zapp-pipes-v2-client": "14.0.0-alpha.3140225604",
|
|
34
|
+
"@applicaster/zapp-react-native-bridge": "14.0.0-alpha.3140225604",
|
|
35
|
+
"@applicaster/zapp-react-native-redux": "14.0.0-alpha.3140225604",
|
|
36
|
+
"@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.3140225604",
|
|
37
|
+
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.3140225604",
|
|
38
38
|
"atob": "^2.1.2",
|
|
39
39
|
"axios": "^0.28.0",
|
|
40
40
|
"btoa": "^1.2.1",
|
|
@@ -67,10 +67,5 @@
|
|
|
67
67
|
"uglify-js": "*",
|
|
68
68
|
"validate-color": "*",
|
|
69
69
|
"zustand": "*"
|
|
70
|
-
}
|
|
71
|
-
"devDependencies": {
|
|
72
|
-
"nock": "^10.0.0",
|
|
73
|
-
"redux-mock-store": "^1.5.3"
|
|
74
|
-
},
|
|
75
|
-
"gitHead": "a473487564142c55cdb50f02505cf0b60fe75658"
|
|
70
|
+
}
|
|
76
71
|
}
|
package/renderZappApp/index.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* @param {React.ComponentType<any>} App component to start
|
|
20
20
|
*/
|
|
21
21
|
export function renderZappApp(options) {
|
|
22
|
-
const { App, AppRegistry, appMountId } = options;
|
|
22
|
+
const { App, AppRegistry, appMountId, mode } = options;
|
|
23
23
|
|
|
24
24
|
if (!App) {
|
|
25
25
|
throw new Error("No App Component provided, nothing to render");
|
|
@@ -37,6 +37,7 @@ export function renderZappApp(options) {
|
|
|
37
37
|
if (appMountId) {
|
|
38
38
|
AppRegistry.runApplication("QuickBrickApp", {
|
|
39
39
|
rootTag: document.getElementById(appMountId),
|
|
40
|
+
mode,
|
|
40
41
|
});
|
|
41
42
|
}
|
|
42
43
|
}
|