@applicaster/quick-brick-core 13.0.0-rc.99 → 14.0.0-alpha.1235043154
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/ActionsProvider/__tests__/__snapshots__/ActionsProvider.test.js.snap +2 -2
- package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/useOpenSchemeHandler.test.tsx +4 -12
- package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/usePresentSchemeHandler.test.tsx +26 -40
- package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/useUrlSchemeHandler.test.tsx +1 -1
- package/App/ModalProvider/ModalBottomSheet/DraggableBottomSheet/index.tsx +25 -3
- package/App/ModalProvider/ModalBottomSheet/ModalBottomSheetFrame.tsx +68 -11
- package/App/ModalProvider/ModalBottomSheet/index.tsx +15 -39
- package/App/ModalProvider/ModalPresenter.tsx +1 -1
- package/App/ModalProvider/index.tsx +5 -1
- package/App/NetworkStatusProvider/__tests__/NetworkStatusProvider.test.tsx +11 -15
- package/App/StoreConnector/__tests__/storeConnector.test.js +6 -9
- package/App/appLifeCycleManager/__tests__/appLifeCycleManager.test.tsx +9 -0
- package/README.md +1 -1
- package/package.json +9 -10
- package/App/ModalProvider/ModalChildrenWrapper/index.ts +0 -1
- /package/App/ModalProvider/ModalChildrenWrapper/{index.android.tsx → index.tsx} +0 -0
|
@@ -12,18 +12,18 @@ exports[`Actions Provider renders children 1`] = `
|
|
|
12
12
|
"$$typeof": Symbol(react.context),
|
|
13
13
|
"Consumer": {
|
|
14
14
|
"$$typeof": Symbol(react.context),
|
|
15
|
-
"_calculateChangedBits": null,
|
|
16
15
|
"_context": [Circular],
|
|
17
16
|
},
|
|
18
17
|
"Provider": {
|
|
19
18
|
"$$typeof": Symbol(react.provider),
|
|
20
19
|
"_context": [Circular],
|
|
21
20
|
},
|
|
22
|
-
"_calculateChangedBits": null,
|
|
23
21
|
"_currentRenderer": null,
|
|
24
22
|
"_currentRenderer2": {},
|
|
25
23
|
"_currentValue": null,
|
|
26
24
|
"_currentValue2": null,
|
|
25
|
+
"_defaultValue": null,
|
|
26
|
+
"_globalName": null,
|
|
27
27
|
"_threadCount": 0,
|
|
28
28
|
},
|
|
29
29
|
"contextProvider": [Function],
|
package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/useOpenSchemeHandler.test.tsx
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "../useOpenSchemeHandler/const";
|
|
17
17
|
import { withInitialPlayerState } from "../useOpenSchemeHandler/utils";
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
import { log_warning } from "../../../logger";
|
|
20
20
|
|
|
21
21
|
const rivers: Record<string, Partial<ZappRiver>> = {
|
|
22
22
|
A1234: {
|
|
@@ -53,13 +53,10 @@ const navigator = {
|
|
|
53
53
|
replace: jest.fn(),
|
|
54
54
|
push: jest.fn(),
|
|
55
55
|
goHome: jest.fn(),
|
|
56
|
-
};
|
|
56
|
+
} as any;
|
|
57
57
|
|
|
58
58
|
const mockStore = configureStore();
|
|
59
|
-
|
|
60
|
-
jest
|
|
61
|
-
.spyOn(useNavigationHooks, "useNavigation")
|
|
62
|
-
.mockImplementation(() => navigator);
|
|
59
|
+
jest.spyOn(useNavigationHooks, "useNavigation").mockReturnValue(navigator);
|
|
63
60
|
|
|
64
61
|
const helperSpy = jest.spyOn(helpers, "handlePresentNavigation");
|
|
65
62
|
const feedLoaderSpy = jest.spyOn(feedLoader, "useFeedLoader");
|
|
@@ -72,7 +69,7 @@ jest.doMock("@applicaster/zapp-react-native-ui-components/Contexts", () => ({
|
|
|
72
69
|
},
|
|
73
70
|
}));
|
|
74
71
|
|
|
75
|
-
jest.
|
|
72
|
+
jest.mock("../../../logger", () => ({
|
|
76
73
|
log_info: jest.fn(),
|
|
77
74
|
log_error: jest.fn(),
|
|
78
75
|
log_warning: jest.fn(),
|
|
@@ -80,10 +77,6 @@ jest.doMock("../../../logger", () => ({
|
|
|
80
77
|
log_debug: jest.fn(),
|
|
81
78
|
}));
|
|
82
79
|
|
|
83
|
-
jest.useFakeTimers({
|
|
84
|
-
legacyFakeTimers: true,
|
|
85
|
-
});
|
|
86
|
-
|
|
87
80
|
// to use import instead of require it's required to use jest.mock above
|
|
88
81
|
const { useOpenSchemeHandler } = require("../useOpenSchemeHandler");
|
|
89
82
|
|
|
@@ -192,7 +185,6 @@ describe("useOpenSchemeHandler", () => {
|
|
|
192
185
|
it("doesn't log a warning", async () => {
|
|
193
186
|
const tests = () => {
|
|
194
187
|
expect(log_warning).not.toHaveBeenCalled();
|
|
195
|
-
expect.assertions(1);
|
|
196
188
|
};
|
|
197
189
|
|
|
198
190
|
await testHook({ url, query, tests });
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
1
|
import * as R from "ramda";
|
|
3
2
|
import axios from "axios";
|
|
4
|
-
import { renderHook } from "@testing-library/react-
|
|
3
|
+
import { renderHook } from "@testing-library/react-native";
|
|
5
4
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
6
|
-
import * as zappRedux from "@applicaster/zapp-react-native-redux";
|
|
7
5
|
import * as helpers from "../../../helpers";
|
|
8
6
|
import * as feedLoader from "@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedLoader";
|
|
9
7
|
import * as useNavigationHooks from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
|
|
8
|
+
import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
9
|
+
import { usePresentSchemeHandler } from "../usePresentSchemeHandler";
|
|
10
10
|
|
|
11
|
-
import { Provider } from "react-redux";
|
|
12
11
|
import configureStore from "redux-mock-store";
|
|
13
12
|
|
|
14
13
|
const rivers = {
|
|
@@ -20,23 +19,22 @@ const rivers = {
|
|
|
20
19
|
const navigator = {
|
|
21
20
|
currentRoute: "/river/A1234",
|
|
22
21
|
replace: jest.fn(),
|
|
23
|
-
|
|
22
|
+
goHome: jest.fn(),
|
|
23
|
+
} as any;
|
|
24
24
|
|
|
25
25
|
const mockStore = configureStore();
|
|
26
26
|
|
|
27
|
-
jest
|
|
28
|
-
.spyOn(useNavigationHooks, "useNavigation")
|
|
29
|
-
.mockImplementation(() => navigator);
|
|
27
|
+
jest.spyOn(useNavigationHooks, "useNavigation").mockReturnValue(navigator);
|
|
30
28
|
|
|
31
29
|
const helperSpy = jest.spyOn(helpers, "handlePresentNavigation");
|
|
32
30
|
const feedLoaderSpy = jest.spyOn(feedLoader, "useFeedLoader");
|
|
33
31
|
|
|
34
|
-
const { usePresentSchemeHandler } = require("../usePresentSchemeHandler");
|
|
35
|
-
|
|
36
32
|
const onFinish = jest.fn((cb) => {
|
|
37
33
|
cb();
|
|
38
34
|
});
|
|
39
35
|
|
|
36
|
+
jest.useFakeTimers();
|
|
37
|
+
|
|
40
38
|
describe("usePresentSchemeHandler", () => {
|
|
41
39
|
beforeEach(() => {
|
|
42
40
|
onFinish.mockClear();
|
|
@@ -44,11 +42,7 @@ describe("usePresentSchemeHandler", () => {
|
|
|
44
42
|
navigator.replace.mockClear();
|
|
45
43
|
});
|
|
46
44
|
|
|
47
|
-
const store =
|
|
48
|
-
|
|
49
|
-
const wrapper: React.FC<any> = ({ children }) => (
|
|
50
|
-
<Provider store={store}>{children}</Provider>
|
|
51
|
-
);
|
|
45
|
+
const store = { test: "test", rivers };
|
|
52
46
|
|
|
53
47
|
describe("loading link url", () => {
|
|
54
48
|
const query = { link_url: "http://applicaster.com" };
|
|
@@ -59,10 +53,11 @@ describe("usePresentSchemeHandler", () => {
|
|
|
59
53
|
|
|
60
54
|
it("opens the link entry", () => {
|
|
61
55
|
renderHook(() => usePresentSchemeHandler({ query, url, onFinish }), {
|
|
62
|
-
wrapper,
|
|
56
|
+
wrapper: WrappedWithProviders,
|
|
57
|
+
initialProps: { store },
|
|
63
58
|
});
|
|
64
59
|
|
|
65
|
-
expect(onFinish).
|
|
60
|
+
expect(onFinish).toHaveBeenCalled();
|
|
66
61
|
|
|
67
62
|
expect(helperSpy).toBeCalledWith(
|
|
68
63
|
expect.objectContaining({
|
|
@@ -96,7 +91,8 @@ describe("usePresentSchemeHandler", () => {
|
|
|
96
91
|
onFinish,
|
|
97
92
|
}),
|
|
98
93
|
{
|
|
99
|
-
wrapper,
|
|
94
|
+
wrapper: WrappedWithProviders,
|
|
95
|
+
initialProps: { store },
|
|
100
96
|
}
|
|
101
97
|
);
|
|
102
98
|
|
|
@@ -123,7 +119,8 @@ describe("usePresentSchemeHandler", () => {
|
|
|
123
119
|
)}&show_nav_bar=true`;
|
|
124
120
|
|
|
125
121
|
renderHook(() => usePresentSchemeHandler({ query, url, onFinish }), {
|
|
126
|
-
wrapper,
|
|
122
|
+
wrapper: WrappedWithProviders,
|
|
123
|
+
initialProps: { store },
|
|
127
124
|
});
|
|
128
125
|
|
|
129
126
|
expect(onFinish).toBeCalled();
|
|
@@ -155,22 +152,22 @@ describe("usePresentSchemeHandler", () => {
|
|
|
155
152
|
)}&screen_id=${screen_id}`;
|
|
156
153
|
|
|
157
154
|
renderHook(() => usePresentSchemeHandler({ query, url, onFinish }), {
|
|
158
|
-
wrapper,
|
|
155
|
+
wrapper: WrappedWithProviders,
|
|
156
|
+
initialProps: { store },
|
|
159
157
|
});
|
|
160
158
|
|
|
161
159
|
expect(onFinish).toBeCalled();
|
|
162
160
|
|
|
163
|
-
expect(helperSpy).
|
|
161
|
+
expect(helperSpy).toHaveBeenCalledWith(
|
|
164
162
|
expect.objectContaining({
|
|
165
163
|
data: {
|
|
166
164
|
id: "url_scheme_entry",
|
|
167
165
|
type: { value: "link" },
|
|
168
|
-
screen_type: screen_id,
|
|
169
166
|
link: { href: query.link_url, type: "text/html" },
|
|
170
167
|
extensions: { showNavBar: false },
|
|
171
168
|
},
|
|
172
|
-
navigator,
|
|
173
|
-
pushScreen:
|
|
169
|
+
navigator: expect.anything(),
|
|
170
|
+
pushScreen: "http://applicaster.com",
|
|
174
171
|
})
|
|
175
172
|
);
|
|
176
173
|
});
|
|
@@ -180,9 +177,7 @@ describe("usePresentSchemeHandler", () => {
|
|
|
180
177
|
it("Re-sets app ready state and calls loadAppContextData with new river and cellStyles data", async () => {
|
|
181
178
|
const store = mockStore({ test: "test" });
|
|
182
179
|
|
|
183
|
-
const wrapper
|
|
184
|
-
<Provider store={store}>{children}</Provider>
|
|
185
|
-
);
|
|
180
|
+
const wrapper = WrappedWithProviders;
|
|
186
181
|
|
|
187
182
|
const query = {
|
|
188
183
|
rivers_configuration_id: "test",
|
|
@@ -190,7 +185,6 @@ describe("usePresentSchemeHandler", () => {
|
|
|
190
185
|
|
|
191
186
|
const storageSpy = jest.spyOn(sessionStorage, "getAllItems");
|
|
192
187
|
const axiosGetSpy = jest.spyOn(axios, "get");
|
|
193
|
-
const zappReduxSpy = jest.spyOn(zappRedux, "loadAppContextData");
|
|
194
188
|
|
|
195
189
|
const getAllItems = jest.fn().mockResolvedValue({
|
|
196
190
|
accountsAccountId: "accountsAccountId",
|
|
@@ -204,7 +198,6 @@ describe("usePresentSchemeHandler", () => {
|
|
|
204
198
|
|
|
205
199
|
storageSpy.mockImplementation(getAllItems);
|
|
206
200
|
axiosGetSpy.mockImplementation(get);
|
|
207
|
-
zappReduxSpy.mockReturnValue(null);
|
|
208
201
|
|
|
209
202
|
renderHook(() => usePresentSchemeHandler({ query, url: "", onFinish }), {
|
|
210
203
|
wrapper,
|
|
@@ -217,13 +210,6 @@ describe("usePresentSchemeHandler", () => {
|
|
|
217
210
|
actions?.find(R.propEq("type", "SET_APP_NOT_READY"))
|
|
218
211
|
).toBeDefined();
|
|
219
212
|
|
|
220
|
-
expect(actions?.find(R.propEq("type", "SET_APP_READY"))).toBeDefined();
|
|
221
|
-
|
|
222
|
-
expect(zappReduxSpy).toBeCalledWith(expect.any(Function), {
|
|
223
|
-
cellStyles: "url",
|
|
224
|
-
rivers: "url",
|
|
225
|
-
});
|
|
226
|
-
|
|
227
213
|
expect(navigator.replace).toBeCalledWith({});
|
|
228
214
|
};
|
|
229
215
|
});
|
|
@@ -261,7 +247,7 @@ describe("usePresentSchemeHandler", () => {
|
|
|
261
247
|
},
|
|
262
248
|
}),
|
|
263
249
|
{
|
|
264
|
-
wrapper,
|
|
250
|
+
wrapper: WrappedWithProviders,
|
|
265
251
|
}
|
|
266
252
|
);
|
|
267
253
|
|
|
@@ -293,7 +279,7 @@ describe("usePresentSchemeHandler", () => {
|
|
|
293
279
|
},
|
|
294
280
|
}),
|
|
295
281
|
{
|
|
296
|
-
wrapper,
|
|
282
|
+
wrapper: WrappedWithProviders,
|
|
297
283
|
}
|
|
298
284
|
);
|
|
299
285
|
|
|
@@ -325,7 +311,7 @@ describe("usePresentSchemeHandler", () => {
|
|
|
325
311
|
},
|
|
326
312
|
}),
|
|
327
313
|
{
|
|
328
|
-
wrapper,
|
|
314
|
+
wrapper: WrappedWithProviders,
|
|
329
315
|
}
|
|
330
316
|
);
|
|
331
317
|
|
|
@@ -357,7 +343,7 @@ describe("usePresentSchemeHandler", () => {
|
|
|
357
343
|
},
|
|
358
344
|
}),
|
|
359
345
|
{
|
|
360
|
-
wrapper,
|
|
346
|
+
wrapper: WrappedWithProviders,
|
|
361
347
|
}
|
|
362
348
|
);
|
|
363
349
|
|
package/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/__tests__/useUrlSchemeHandler.test.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import * as URLHandlersMap from "..";
|
|
|
5
5
|
import { Provider } from "react-redux";
|
|
6
6
|
import configureStore from "redux-mock-store";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
import { log_warning } from "../../../logger";
|
|
9
9
|
|
|
10
10
|
const mockStore = configureStore();
|
|
11
11
|
|
|
@@ -56,6 +56,7 @@ export class DraggableBottomSheet extends Component<Props, ComponentState> {
|
|
|
56
56
|
_translateYOffset: Animated.Value;
|
|
57
57
|
_translateY: Animated.AnimatedAddition;
|
|
58
58
|
_snapPoints: SnapPoints;
|
|
59
|
+
_prevContentHeight = 0;
|
|
59
60
|
|
|
60
61
|
_callWhenMounted: () => void | null;
|
|
61
62
|
|
|
@@ -89,6 +90,14 @@ export class DraggableBottomSheet extends Component<Props, ComponentState> {
|
|
|
89
90
|
this._lastScrollY
|
|
90
91
|
);
|
|
91
92
|
|
|
93
|
+
const initialSnapPoints = new SnapPoints(props.height, props.sheetHeight);
|
|
94
|
+
|
|
95
|
+
this._translateYOffset = new Animated.Value(
|
|
96
|
+
props.visible ? initialSnapPoints.top : initialSnapPoints.bottom
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
this._prevContentHeight = initialSnapPoints.contentHeight;
|
|
100
|
+
|
|
92
101
|
this.state = {
|
|
93
102
|
lastSnap: props.height,
|
|
94
103
|
dragging: false,
|
|
@@ -150,12 +159,25 @@ export class DraggableBottomSheet extends Component<Props, ComponentState> {
|
|
|
150
159
|
|
|
151
160
|
if (!this._snapPoints) {
|
|
152
161
|
this._snapPoints = new SnapPoints(windowHeight, totalSheetHeight);
|
|
162
|
+
this._prevContentHeight = totalSheetHeight;
|
|
153
163
|
} else {
|
|
154
164
|
this._snapPoints.windowHeight = windowHeight;
|
|
155
165
|
this._snapPoints.contentHeight = totalSheetHeight;
|
|
156
|
-
}
|
|
157
166
|
|
|
158
|
-
|
|
167
|
+
if (this.props.visible && this._isMounted) {
|
|
168
|
+
Animated.timing(this._translateYOffset, {
|
|
169
|
+
toValue: this._snapPoints.top,
|
|
170
|
+
duration: ANIMATION_DURATION,
|
|
171
|
+
easing: ANIMATION_EASING,
|
|
172
|
+
delay: ANIMATION_DELAY,
|
|
173
|
+
useNativeDriver: USE_NATIVE_DRIVER,
|
|
174
|
+
}).start();
|
|
175
|
+
} else {
|
|
176
|
+
this._translateYOffset.setValue(this._snapPoints.top);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
this._prevContentHeight = totalSheetHeight;
|
|
180
|
+
}
|
|
159
181
|
|
|
160
182
|
this._translateY = Animated.add(
|
|
161
183
|
this._translateYOffset,
|
|
@@ -254,6 +276,7 @@ export class DraggableBottomSheet extends Component<Props, ComponentState> {
|
|
|
254
276
|
getDraggableAreaStyles() {
|
|
255
277
|
return {
|
|
256
278
|
width: this.props.maxWidth,
|
|
279
|
+
top: 0,
|
|
257
280
|
left: (this.props.width - this.props.maxWidth) / 2 || 0,
|
|
258
281
|
};
|
|
259
282
|
}
|
|
@@ -300,7 +323,6 @@ export class DraggableBottomSheet extends Component<Props, ComponentState> {
|
|
|
300
323
|
simultaneousHandlers={this.drawer}
|
|
301
324
|
>
|
|
302
325
|
<Animated.ScrollView
|
|
303
|
-
style={{ marginBottom: this._snapPoints.top }}
|
|
304
326
|
bounces={false}
|
|
305
327
|
onScrollBeginDrag={this._onRegisterLastScroll}
|
|
306
328
|
scrollEventThrottle={1}
|
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { StyleSheet, View } from "react-native";
|
|
2
|
+
import { LayoutChangeEvent, Platform, StyleSheet, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import { Handle, HandleProps } from "./Handle";
|
|
5
5
|
import { DraggableBottomSheet } from "./DraggableBottomSheet";
|
|
6
|
+
import {
|
|
7
|
+
SafeAreaView,
|
|
8
|
+
useSafeAreaFrame,
|
|
9
|
+
useSafeAreaInsets,
|
|
10
|
+
} from "react-native-safe-area-context";
|
|
11
|
+
import {
|
|
12
|
+
isAndroidPlatform,
|
|
13
|
+
isAndroidVersionAtLeast,
|
|
14
|
+
platformSelect,
|
|
15
|
+
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
6
16
|
|
|
7
17
|
type Props = {
|
|
8
18
|
children: React.ReactChild;
|
|
9
19
|
backgroundColor: string;
|
|
10
20
|
cornerRadius: number;
|
|
11
|
-
contentHeight: number;
|
|
12
21
|
maxHeight: number;
|
|
13
22
|
maxWidth: number;
|
|
14
23
|
visible: boolean;
|
|
15
24
|
handleProps: HandleProps;
|
|
16
25
|
closeToast: () => void;
|
|
17
|
-
dimensions: {
|
|
18
|
-
|
|
26
|
+
dimensions: {
|
|
27
|
+
statusBarHeight: any;
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
};
|
|
19
31
|
};
|
|
20
32
|
|
|
21
33
|
const styles = StyleSheet.create({
|
|
@@ -25,6 +37,32 @@ const styles = StyleSheet.create({
|
|
|
25
37
|
},
|
|
26
38
|
});
|
|
27
39
|
|
|
40
|
+
const defaultBottomOffset = platformSelect({
|
|
41
|
+
ios: 34,
|
|
42
|
+
android: 0,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const getSheetHeight = ({ height, bottomOffset, maxHeight }) => {
|
|
46
|
+
return platformSelect({
|
|
47
|
+
ios: height - bottomOffset,
|
|
48
|
+
default:
|
|
49
|
+
(height || maxHeight) -
|
|
50
|
+
(!isAndroidVersionAtLeast(35) && isAndroidPlatform() ? bottomOffset : 0),
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const useGetSheetHeight = (height, maxHeight) => {
|
|
55
|
+
const { bottom = defaultBottomOffset } = useSafeAreaInsets();
|
|
56
|
+
|
|
57
|
+
const bottomOffset = bottom;
|
|
58
|
+
|
|
59
|
+
return getSheetHeight({
|
|
60
|
+
height,
|
|
61
|
+
bottomOffset,
|
|
62
|
+
maxHeight,
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
28
66
|
export function ModalBottomSheetFrame(props: Props) {
|
|
29
67
|
const {
|
|
30
68
|
children,
|
|
@@ -34,31 +72,50 @@ export function ModalBottomSheetFrame(props: Props) {
|
|
|
34
72
|
maxWidth,
|
|
35
73
|
visible,
|
|
36
74
|
handleProps,
|
|
37
|
-
contentHeight,
|
|
38
75
|
dimensions,
|
|
39
|
-
paddingBottom,
|
|
40
76
|
} = props;
|
|
41
77
|
|
|
78
|
+
const safeAreaDims = useSafeAreaFrame();
|
|
79
|
+
|
|
42
80
|
const extraStyles = {
|
|
43
81
|
backgroundColor,
|
|
44
82
|
borderTopLeftRadius: cornerRadius,
|
|
45
83
|
borderTopRightRadius: cornerRadius,
|
|
46
84
|
maxHeight,
|
|
47
|
-
|
|
48
|
-
|
|
85
|
+
maxWidth: Math.min(Number(maxWidth), safeAreaDims.width),
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const [height, setHeight] = React.useState(0);
|
|
89
|
+
|
|
90
|
+
const onLayout = (event: LayoutChangeEvent) => {
|
|
91
|
+
const { height } = event.nativeEvent.layout;
|
|
92
|
+
|
|
93
|
+
if (height !== 0) {
|
|
94
|
+
setHeight(height);
|
|
95
|
+
}
|
|
49
96
|
};
|
|
50
97
|
|
|
98
|
+
const { bottom = defaultBottomOffset } = useSafeAreaInsets();
|
|
99
|
+
|
|
100
|
+
const sheetHeight = useGetSheetHeight(height, maxHeight);
|
|
101
|
+
|
|
51
102
|
return (
|
|
52
103
|
<DraggableBottomSheet
|
|
53
|
-
sheetHeight={
|
|
54
|
-
visible={visible}
|
|
104
|
+
sheetHeight={sheetHeight}
|
|
105
|
+
visible={height > 0 && visible}
|
|
55
106
|
dismiss={props.closeToast}
|
|
56
107
|
hasHeader={handleProps.enabled}
|
|
57
108
|
header={(dragging) => <Handle {...handleProps} focused={dragging} />}
|
|
58
109
|
maxWidth={maxWidth}
|
|
59
110
|
{...dimensions}
|
|
111
|
+
height={safeAreaDims.height - (Platform.OS === "ios" ? bottom : 0)}
|
|
60
112
|
>
|
|
61
|
-
<
|
|
113
|
+
<SafeAreaView
|
|
114
|
+
edges={["left", "right", "bottom"]}
|
|
115
|
+
style={[styles.toastFrameContainer, extraStyles]}
|
|
116
|
+
>
|
|
117
|
+
<View onLayout={onLayout}>{children}</View>
|
|
118
|
+
</SafeAreaView>
|
|
62
119
|
</DraggableBottomSheet>
|
|
63
120
|
);
|
|
64
121
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/// <reference types="@applicaster/applicaster-types" />
|
|
2
2
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
3
|
-
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
4
|
-
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
5
3
|
|
|
6
4
|
import React, { useCallback, useEffect, useState } from "react";
|
|
7
5
|
import { Keyboard, StyleSheet, View } from "react-native";
|
|
@@ -29,56 +27,39 @@ type Props = {
|
|
|
29
27
|
modalBottomSheetContentProps: Record<string, any>;
|
|
30
28
|
};
|
|
31
29
|
|
|
32
|
-
const defaultBottomOffset = platformSelect({
|
|
33
|
-
ios: 34,
|
|
34
|
-
android: 0,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
30
|
export function ModalBottomSheet(props: Props) {
|
|
38
31
|
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
39
32
|
const navigator = useNavigation();
|
|
40
33
|
const dimensions = useDimensions();
|
|
41
|
-
const [sheetHeight, setSheetHeight] = useState(0);
|
|
42
34
|
const [visible, setVisible] = useState(true);
|
|
43
|
-
const dismiss = () => setVisible(false);
|
|
44
|
-
const { bottom = defaultBottomOffset } = useSafeAreaInsets();
|
|
45
|
-
|
|
46
|
-
const bottomOffset = bottom + dimensions.statusBarHeight;
|
|
47
35
|
|
|
48
36
|
const {
|
|
49
37
|
modal_bottom_sheet_background_color: sheetBackgroundColor,
|
|
50
38
|
modal_bottom_sheet_overlay_color: sheetOverlayColor,
|
|
51
39
|
modal_bottom_sheet_top_corner_radius: sheetCornerRadius,
|
|
52
|
-
modal_bottom_sheet_max_height: sheetMaxHeight,
|
|
53
40
|
modal_bottom_sheet_handle: sheetHandleEnabled,
|
|
54
41
|
modal_bottom_sheet_handle_color: sheetHandleColor,
|
|
55
42
|
modal_bottom_sheet_handle_focus_color: sheetHandleFocusedColor,
|
|
56
43
|
modal_bottom_sheet_tablet_max_width: sheetTabletMaxWidth,
|
|
57
44
|
} = theme;
|
|
58
45
|
|
|
46
|
+
const sheetMaxHeight = dimensions.height * 0.75; // Set a default max height
|
|
47
|
+
|
|
59
48
|
const {
|
|
60
49
|
ModalBottomSheetContent = ModalComponent,
|
|
61
50
|
modalBottomSheetContentProps,
|
|
62
51
|
} = props;
|
|
63
52
|
|
|
64
|
-
const onLayout = useCallback(({ nativeEvent }) => {
|
|
65
|
-
const calculatedHeight = nativeEvent?.layout?.height;
|
|
66
|
-
|
|
67
|
-
if (calculatedHeight > 0 && sheetHeight === 0) {
|
|
68
|
-
setSheetHeight(Math.min(calculatedHeight, sheetMaxHeight));
|
|
69
|
-
}
|
|
70
|
-
}, []);
|
|
71
|
-
|
|
72
53
|
useEffect(() => {
|
|
73
54
|
Keyboard.dismiss();
|
|
74
55
|
}, []);
|
|
75
56
|
|
|
57
|
+
const dismiss = useCallback(() => setVisible(false), []);
|
|
58
|
+
|
|
76
59
|
const isTablet = useIsTablet();
|
|
77
60
|
|
|
78
61
|
const maxWidth = isTablet ? sheetTabletMaxWidth : dimensions.width;
|
|
79
62
|
|
|
80
|
-
const modalVisible = visible && sheetHeight > 0;
|
|
81
|
-
|
|
82
63
|
return (
|
|
83
64
|
<View style={styles.container}>
|
|
84
65
|
<Overlay
|
|
@@ -89,12 +70,10 @@ export function ModalBottomSheet(props: Props) {
|
|
|
89
70
|
<ModalBottomSheetFrame
|
|
90
71
|
backgroundColor={sheetBackgroundColor}
|
|
91
72
|
cornerRadius={sheetCornerRadius}
|
|
92
|
-
|
|
93
|
-
maxHeight={sheetMaxHeight + bottomOffset}
|
|
94
|
-
paddingBottom={bottomOffset}
|
|
73
|
+
maxHeight={sheetMaxHeight}
|
|
95
74
|
maxWidth={maxWidth}
|
|
96
75
|
dimensions={dimensions}
|
|
97
|
-
visible={
|
|
76
|
+
visible={visible}
|
|
98
77
|
closeToast={dismiss}
|
|
99
78
|
handleProps={{
|
|
100
79
|
enabled: sheetHandleEnabled,
|
|
@@ -102,18 +81,15 @@ export function ModalBottomSheet(props: Props) {
|
|
|
102
81
|
focusedColor: sheetHandleFocusedColor,
|
|
103
82
|
}}
|
|
104
83
|
>
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
width
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
currentRoute={navigator.currentRoute}
|
|
115
|
-
/>
|
|
116
|
-
</View>
|
|
84
|
+
<ModalBottomSheetContent
|
|
85
|
+
width={
|
|
86
|
+
Math.min(sheetTabletMaxWidth, dimensions.width) || dimensions.width
|
|
87
|
+
}
|
|
88
|
+
maxHeight={sheetMaxHeight}
|
|
89
|
+
{...modalBottomSheetContentProps}
|
|
90
|
+
dismiss={dismiss}
|
|
91
|
+
currentRoute={navigator.currentRoute}
|
|
92
|
+
/>
|
|
117
93
|
</ModalBottomSheetFrame>
|
|
118
94
|
</View>
|
|
119
95
|
);
|
|
@@ -40,7 +40,11 @@ export function ModalProvider() {
|
|
|
40
40
|
return (
|
|
41
41
|
<PathnameContext.Provider value={pathname}>
|
|
42
42
|
<ScreenContextProvider pathname={pathname}>
|
|
43
|
-
<ModalPresenter
|
|
43
|
+
<ModalPresenter
|
|
44
|
+
visible={shouldShowModal}
|
|
45
|
+
{...modalState?.options}
|
|
46
|
+
statusBarTranslucent
|
|
47
|
+
>
|
|
44
48
|
<ModalChildrenWrapper>
|
|
45
49
|
<ModalContent modalScreenProps={modalScreenProps} />
|
|
46
50
|
</ModalChildrenWrapper>
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
import { renderHook, act } from "@testing-library/react-hooks";
|
|
4
|
-
import configureStore from "redux-mock-store";
|
|
5
|
-
import thunk from "redux-thunk";
|
|
6
4
|
import { NetworkStatusContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NetworkStatusContext";
|
|
7
5
|
import { NetworkStatusProvider } from "../NetworkStatusProvider";
|
|
8
|
-
import {
|
|
6
|
+
import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
9
7
|
import NetInfo from "@react-native-community/netinfo";
|
|
10
8
|
|
|
11
|
-
const mockStore = configureStore([thunk]);
|
|
12
|
-
|
|
13
9
|
const NetInfoMock = {
|
|
14
10
|
type: "cellular",
|
|
15
11
|
details: {
|
|
@@ -24,9 +20,9 @@ const NetInfoMock = {
|
|
|
24
20
|
const getWrapper = (store) => ({
|
|
25
21
|
// eslint-disable-next-line react/prop-types,react/display-name
|
|
26
22
|
wrapper: ({ children }) => (
|
|
27
|
-
<
|
|
23
|
+
<WrappedWithProviders store={store}>
|
|
28
24
|
<NetworkStatusProvider>{children}</NetworkStatusProvider>
|
|
29
|
-
</
|
|
25
|
+
</WrappedWithProviders>
|
|
30
26
|
),
|
|
31
27
|
});
|
|
32
28
|
|
|
@@ -41,9 +37,9 @@ const useNetInfoMock = () => {
|
|
|
41
37
|
|
|
42
38
|
describe("NetworkStatusProvider", function () {
|
|
43
39
|
it("should return netInfoData", function () {
|
|
44
|
-
const store =
|
|
40
|
+
const store = {
|
|
45
41
|
plugins: [{}],
|
|
46
|
-
}
|
|
42
|
+
};
|
|
47
43
|
|
|
48
44
|
// @ts-ignore
|
|
49
45
|
jest.spyOn(NetInfo, "useNetInfo").mockImplementation(useNetInfoMock);
|
|
@@ -59,9 +55,9 @@ describe("NetworkStatusProvider", function () {
|
|
|
59
55
|
it("should call onConnectionLost callback when connection type changes to none", function () {
|
|
60
56
|
const onConnectionLost = jest.fn();
|
|
61
57
|
|
|
62
|
-
const store =
|
|
58
|
+
const store = {
|
|
63
59
|
plugins: [{ module: { networkHooks: { onConnectionLost } } }],
|
|
64
|
-
}
|
|
60
|
+
};
|
|
65
61
|
|
|
66
62
|
// @ts-ignore
|
|
67
63
|
jest.spyOn(NetInfo, "useNetInfo").mockImplementation(useNetInfoMock);
|
|
@@ -86,9 +82,9 @@ describe("NetworkStatusProvider", function () {
|
|
|
86
82
|
it("should call onConnectionRestored callback when connection type switches from none", function () {
|
|
87
83
|
const onConnectionRestored = jest.fn();
|
|
88
84
|
|
|
89
|
-
const store =
|
|
85
|
+
const store = {
|
|
90
86
|
plugins: [{ module: { networkHooks: { onConnectionRestored } } }],
|
|
91
|
-
}
|
|
87
|
+
};
|
|
92
88
|
|
|
93
89
|
// @ts-ignore
|
|
94
90
|
jest.spyOn(NetInfo, "useNetInfo").mockImplementation(useNetInfoMock);
|
|
@@ -123,9 +119,9 @@ describe("NetworkStatusProvider", function () {
|
|
|
123
119
|
it("should call onConnectionTypeChanged callback when connection type changes", function () {
|
|
124
120
|
const onConnectionTypeChanged = jest.fn();
|
|
125
121
|
|
|
126
|
-
const store =
|
|
122
|
+
const store = {
|
|
127
123
|
plugins: [{ module: { networkHooks: { onConnectionTypeChanged } } }],
|
|
128
|
-
}
|
|
124
|
+
};
|
|
129
125
|
|
|
130
126
|
// @ts-ignore
|
|
131
127
|
jest.spyOn(NetInfo, "useNetInfo").mockImplementation(useNetInfoMock);
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as ReactIs from "react-is";
|
|
3
3
|
import { View, Text } from "react-native";
|
|
4
|
-
import {
|
|
5
|
-
import configureStore from "redux-mock-store";
|
|
4
|
+
import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
6
5
|
|
|
7
6
|
import { storeConnector } from "../index";
|
|
8
|
-
import { Provider } from "react-redux";
|
|
9
7
|
|
|
10
8
|
const styles = { foo: "bar" };
|
|
11
9
|
const components = { grid: jest.fn() };
|
|
@@ -18,12 +16,12 @@ const Component = (props) => (
|
|
|
18
16
|
</View>
|
|
19
17
|
);
|
|
20
18
|
|
|
21
|
-
const store =
|
|
19
|
+
const store = {
|
|
22
20
|
styles,
|
|
23
21
|
components,
|
|
24
22
|
rivers,
|
|
25
23
|
appSettings,
|
|
26
|
-
}
|
|
24
|
+
};
|
|
27
25
|
|
|
28
26
|
describe("storeConnector", () => {
|
|
29
27
|
it("returns a Component", () => {
|
|
@@ -41,10 +39,9 @@ describe("storeConnector", () => {
|
|
|
41
39
|
it("passes the props to the component", () => {
|
|
42
40
|
const WrappedComponent = storeConnector(Component);
|
|
43
41
|
|
|
44
|
-
const { getByText, getByTestId } =
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
</Provider>
|
|
42
|
+
const { getByText, getByTestId } = renderWithProviders(
|
|
43
|
+
<WrappedComponent />,
|
|
44
|
+
store
|
|
48
45
|
);
|
|
49
46
|
|
|
50
47
|
expect(getByText("I'm a component")).toBeTruthy();
|
|
@@ -10,6 +10,15 @@ import { appLifeCycleManager } from "../";
|
|
|
10
10
|
|
|
11
11
|
const mock_actions = {};
|
|
12
12
|
|
|
13
|
+
jest.mock(
|
|
14
|
+
"@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage",
|
|
15
|
+
() => ({
|
|
16
|
+
sessionStorage: {
|
|
17
|
+
getAllItems: jest.fn(() => Promise.resolve(mocked_items)),
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
|
+
);
|
|
21
|
+
|
|
13
22
|
jest.mock("@applicaster/zapp-react-native-redux/AppData", () => ({
|
|
14
23
|
loadAppData: jest.fn(() => () => Promise.resolve()),
|
|
15
24
|
}));
|
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ This function allows to quickly create a QuickBrick app by providing the require
|
|
|
74
74
|
|
|
75
75
|
## NavigationProvider
|
|
76
76
|
|
|
77
|
-
This module provides routing, navigation and navBar control to the QuickBrick applications. The Navigator provider is constructed using NavigationContext and navigator object, which are exposed to the user by `withNavigator` Decorator and `useNavigation` hook.
|
|
77
|
+
This module provides routing, navigation and navBar control to the QuickBrick applications. The Navigator provider is constructed using NavigationContext and navigator object, which are exposed to the user by `withNavigator` Decorator and `useNavigation` hook.
|
|
78
78
|
|
|
79
79
|
The app is already decorated with the Navigation Provider Context so the only thing, to use navigation in your screen/component`is to use`withNavigator`decorator or`useNavigationHook` directly
|
|
80
80
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0-alpha.1235043154",
|
|
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": "
|
|
32
|
-
"@applicaster/quick-brick-core-plugins": "
|
|
33
|
-
"@applicaster/zapp-pipes-v2-client": "
|
|
34
|
-
"@applicaster/zapp-react-native-bridge": "
|
|
35
|
-
"@applicaster/zapp-react-native-redux": "
|
|
36
|
-
"@applicaster/zapp-react-native-ui-components": "
|
|
37
|
-
"@applicaster/zapp-react-native-utils": "
|
|
31
|
+
"@applicaster/applicaster-types": "14.0.0-alpha.1235043154",
|
|
32
|
+
"@applicaster/quick-brick-core-plugins": "14.0.0-alpha.1235043154",
|
|
33
|
+
"@applicaster/zapp-pipes-v2-client": "14.0.0-alpha.1235043154",
|
|
34
|
+
"@applicaster/zapp-react-native-bridge": "14.0.0-alpha.1235043154",
|
|
35
|
+
"@applicaster/zapp-react-native-redux": "14.0.0-alpha.1235043154",
|
|
36
|
+
"@applicaster/zapp-react-native-ui-components": "14.0.0-alpha.1235043154",
|
|
37
|
+
"@applicaster/zapp-react-native-utils": "14.0.0-alpha.1235043154",
|
|
38
38
|
"atob": "^2.1.2",
|
|
39
39
|
"axios": "^0.28.0",
|
|
40
40
|
"btoa": "^1.2.1",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"md5": "^2.3.0",
|
|
43
43
|
"promise": "^8.3.0",
|
|
44
44
|
"query-string": "7.1.3",
|
|
45
|
-
"react-redux": "
|
|
45
|
+
"react-redux": "9.2.0",
|
|
46
46
|
"redux": "^4.0.4",
|
|
47
47
|
"reselect": "^4.0.0",
|
|
48
48
|
"url": "^0.11.0",
|
|
@@ -62,7 +62,6 @@
|
|
|
62
62
|
"react-native-fs": "*",
|
|
63
63
|
"react-native-gesture-handler": "*",
|
|
64
64
|
"react-native-linear-gradient": "*",
|
|
65
|
-
"react-native-safe-area-context": "*",
|
|
66
65
|
"react-native-svg": "*",
|
|
67
66
|
"react-native-web": "*",
|
|
68
67
|
"react-native-webview": "*",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Fragment as ModalChildrenWrapper } from "react";
|
|
File without changes
|