@applicaster/zapp-react-native-ui-components 15.0.0-alpha.2060204268 → 15.0.0-alpha.2210182446
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/Components/HandlePlayable/HandlePlayable.tsx +16 -29
- package/Components/HandlePlayable/utils.ts +31 -0
- package/Components/PlayerContainer/PlayerContainer.tsx +1 -2
- package/Components/PlayerContainer/useRestrictMobilePlayback.tsx +39 -9
- package/Components/Screen/__tests__/Screen.test.tsx +1 -0
- package/Components/Screen/hooks.ts +73 -3
- package/Components/Screen/index.tsx +7 -1
- package/Components/Transitioner/Scene.tsx +9 -15
- package/Components/Viewport/ViewportAware/index.tsx +16 -7
- package/package.json +5 -5
|
@@ -5,8 +5,6 @@ import {
|
|
|
5
5
|
usePlugins,
|
|
6
6
|
} from "@applicaster/zapp-react-native-redux/hooks";
|
|
7
7
|
import {
|
|
8
|
-
useDimensions,
|
|
9
|
-
useIsTablet as isTablet,
|
|
10
8
|
useNavigation,
|
|
11
9
|
useRivers,
|
|
12
10
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
@@ -15,8 +13,8 @@ import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
|
|
|
15
13
|
import { PlayerContainer } from "../PlayerContainer";
|
|
16
14
|
import { useModalSize } from "../VideoModal/hooks";
|
|
17
15
|
import { ViewStyle } from "react-native";
|
|
18
|
-
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
19
16
|
import { findCastPlugin, getPlayer } from "./utils";
|
|
17
|
+
import { useWaitForValidOrientation } from "../Screen/hooks";
|
|
20
18
|
|
|
21
19
|
type Props = {
|
|
22
20
|
item: ZappEntry;
|
|
@@ -31,13 +29,6 @@ type PlayableComponent = {
|
|
|
31
29
|
Component: React.ComponentType<any>;
|
|
32
30
|
};
|
|
33
31
|
|
|
34
|
-
const dimensionsContext: "window" | "screen" = platformSelect({
|
|
35
|
-
android_tv: "window",
|
|
36
|
-
amazon: "window",
|
|
37
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
38
|
-
default: isTablet() ? "window" : "screen", // on tablet, window represents correct values, on phone it's not as the screen could be rotated
|
|
39
|
-
});
|
|
40
|
-
|
|
41
32
|
export function HandlePlayable({
|
|
42
33
|
item,
|
|
43
34
|
isModal,
|
|
@@ -97,27 +88,23 @@ export function HandlePlayable({
|
|
|
97
88
|
});
|
|
98
89
|
}, [casting]);
|
|
99
90
|
|
|
100
|
-
const { width: screenWidth, height: screenHeight } =
|
|
101
|
-
useDimensions(dimensionsContext);
|
|
102
|
-
|
|
103
91
|
const modalSize = useModalSize();
|
|
104
92
|
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
);
|
|
93
|
+
const isOrientationReady = useWaitForValidOrientation();
|
|
94
|
+
|
|
95
|
+
const style = React.useMemo(() => {
|
|
96
|
+
const isFullScreenReady =
|
|
97
|
+
mode === "PIP" || (mode === "FULLSCREEN" && isOrientationReady);
|
|
98
|
+
|
|
99
|
+
const getDimensionValue = (value: string | number) => {
|
|
100
|
+
return isModal ? value : isFullScreenReady ? "100%" : 0; // do not show player, until full screen mode is ready
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
width: getDimensionValue(modalSize.width),
|
|
105
|
+
height: getDimensionValue(modalSize.height),
|
|
106
|
+
} as ViewStyle;
|
|
107
|
+
}, [modalSize, isModal, mode, isOrientationReady]);
|
|
121
108
|
|
|
122
109
|
const Component = playable?.Component;
|
|
123
110
|
|
|
@@ -5,6 +5,14 @@ import {
|
|
|
5
5
|
|
|
6
6
|
import { CHROMECAST_PLUGIN_ID, YOUTUBE_PLUGIN_ID } from "./const";
|
|
7
7
|
import { omit } from "@applicaster/zapp-react-native-utils/utils";
|
|
8
|
+
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
9
|
+
|
|
10
|
+
const { Logger } = getXray();
|
|
11
|
+
|
|
12
|
+
const logger = new Logger(
|
|
13
|
+
"QuickBrick",
|
|
14
|
+
"packages/zapp-react-native-ui-components/Components/HandlePlayable"
|
|
15
|
+
);
|
|
8
16
|
|
|
9
17
|
const getPlayerModuleProperties = (PlayerModule: ZappPlugin) => {
|
|
10
18
|
if (PlayerModule?.Component && typeof PlayerModule.Component === "object") {
|
|
@@ -52,10 +60,25 @@ export const getPlayer = (
|
|
|
52
60
|
if (type) {
|
|
53
61
|
PlayerModule = findPluginByIdentifier(type, plugins)?.module;
|
|
54
62
|
|
|
63
|
+
if (!PlayerModule) {
|
|
64
|
+
logger.error({
|
|
65
|
+
message:
|
|
66
|
+
"PlayerModule is undefined – type mapping may be wrong or type not set for player",
|
|
67
|
+
data: {
|
|
68
|
+
type,
|
|
69
|
+
screen_id,
|
|
70
|
+
item_type_value: item?.type?.value,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return [null, {}];
|
|
75
|
+
}
|
|
76
|
+
|
|
55
77
|
return getPlayerWithModuleProperties(PlayerModule);
|
|
56
78
|
}
|
|
57
79
|
}
|
|
58
80
|
|
|
81
|
+
// TODO: Probably should be removed, Youtube plugin is deprecated
|
|
59
82
|
if (item?.content?.type === "youtube-id") {
|
|
60
83
|
PlayerModule = findYoutubePlugin(plugins)?.module;
|
|
61
84
|
|
|
@@ -70,5 +93,13 @@ export const getPlayer = (
|
|
|
70
93
|
)
|
|
71
94
|
);
|
|
72
95
|
|
|
96
|
+
if (!PlayerModule) {
|
|
97
|
+
logger.error({
|
|
98
|
+
message: "PlayerModule is undefined – playable plugin not found",
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return [null, {}];
|
|
102
|
+
}
|
|
103
|
+
|
|
73
104
|
return getPlayerWithModuleProperties(PlayerModule);
|
|
74
105
|
};
|
|
@@ -277,7 +277,6 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
277
277
|
const { isRestricted } = useRestrictMobilePlayback({
|
|
278
278
|
player,
|
|
279
279
|
entry: item,
|
|
280
|
-
pluginConfiguration,
|
|
281
280
|
close,
|
|
282
281
|
});
|
|
283
282
|
|
|
@@ -670,7 +669,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
670
669
|
<PlayerFocusableWrapperView
|
|
671
670
|
nextFocusDown={context.bottomFocusableId}
|
|
672
671
|
>
|
|
673
|
-
{isRestricted ? null : (
|
|
672
|
+
{!Player || isRestricted ? null : (
|
|
674
673
|
<Player
|
|
675
674
|
source={{
|
|
676
675
|
uri,
|
|
@@ -1,27 +1,50 @@
|
|
|
1
1
|
import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
|
|
2
2
|
import NetInfo from "@react-native-community/netinfo";
|
|
3
3
|
|
|
4
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { showAlertDialog } from "@applicaster/zapp-react-native-utils/alertUtils";
|
|
6
6
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
7
7
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
8
|
+
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
|
|
9
|
+
import { usePlugins } from "@applicaster/zapp-react-native-redux/hooks";
|
|
10
|
+
import { getLocalizations } from "@applicaster/zapp-react-native-utils/localizationUtils";
|
|
8
11
|
import { log_info } from "./logger";
|
|
12
|
+
import { isTrue } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
9
13
|
|
|
10
14
|
type RestrictMobilePlaybackProps = {
|
|
11
15
|
player?: Player;
|
|
12
16
|
entry?: ZappEntry;
|
|
13
|
-
pluginConfiguration?: Record<string, string>;
|
|
14
17
|
close: () => void;
|
|
15
18
|
};
|
|
16
19
|
|
|
17
20
|
export const useRestrictMobilePlayback = ({
|
|
18
21
|
player,
|
|
19
22
|
entry,
|
|
20
|
-
pluginConfiguration,
|
|
21
23
|
close,
|
|
22
24
|
}: RestrictMobilePlaybackProps): { isRestricted: boolean } => {
|
|
23
25
|
const dialogVisibleRef = useRef<boolean>(false);
|
|
24
26
|
const theme = useTheme();
|
|
27
|
+
const plugins = usePlugins();
|
|
28
|
+
|
|
29
|
+
const restrictMobilePlugin = useMemo(
|
|
30
|
+
() =>
|
|
31
|
+
plugins.find((p) => p.identifier === "quick-brick-hook-restrict-mobile"),
|
|
32
|
+
[plugins]
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const localizations = useMemo(
|
|
36
|
+
() => restrictMobilePlugin?.configuration?.localizations,
|
|
37
|
+
[restrictMobilePlugin]
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const localize = useCallback(
|
|
41
|
+
(key: string) => {
|
|
42
|
+
const l = localizations && getLocalizations({ localizations });
|
|
43
|
+
|
|
44
|
+
return (l && l[key]) || "";
|
|
45
|
+
},
|
|
46
|
+
[localizations]
|
|
47
|
+
);
|
|
25
48
|
|
|
26
49
|
useEffect(() => {
|
|
27
50
|
return () => {
|
|
@@ -38,8 +61,13 @@ export const useRestrictMobilePlayback = ({
|
|
|
38
61
|
return false;
|
|
39
62
|
}
|
|
40
63
|
|
|
41
|
-
|
|
42
|
-
|
|
64
|
+
// Only restrict if the plugin exists
|
|
65
|
+
if (!restrictMobilePlugin) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return player && isTrue(entry?.extensions?.connection_restricted);
|
|
70
|
+
}, [player, entry, restrictMobilePlugin]);
|
|
43
71
|
|
|
44
72
|
const [isRestricted, setIsRestricted] = useState<boolean>(
|
|
45
73
|
isConnectionRestricted
|
|
@@ -55,16 +83,17 @@ export const useRestrictMobilePlayback = ({
|
|
|
55
83
|
"Stopping player due to mobile restriction, connection_restricted: true"
|
|
56
84
|
);
|
|
57
85
|
|
|
58
|
-
player?.
|
|
86
|
+
player?.closeNativePlayer();
|
|
87
|
+
playerManager?.invokeHandler("close");
|
|
59
88
|
|
|
60
89
|
dialogVisibleRef.current = true;
|
|
61
90
|
|
|
62
91
|
showAlertDialog({
|
|
63
92
|
title:
|
|
64
|
-
|
|
93
|
+
localize("restrict_mobile_playback_error_title") ||
|
|
65
94
|
"Restricted Connection Type",
|
|
66
95
|
message:
|
|
67
|
-
|
|
96
|
+
localize("restrict_mobile_playback_error_message") ||
|
|
68
97
|
"This content can only be viewed over a Wi-Fi or LAN network.",
|
|
69
98
|
okButtonText: theme.ok_button || "OK",
|
|
70
99
|
completion: () => {
|
|
@@ -91,7 +120,8 @@ export const useRestrictMobilePlayback = ({
|
|
|
91
120
|
}, [
|
|
92
121
|
close,
|
|
93
122
|
entry?.extensions?.connection_restricted,
|
|
94
|
-
|
|
123
|
+
localizations,
|
|
124
|
+
localize,
|
|
95
125
|
player,
|
|
96
126
|
theme.ok_button,
|
|
97
127
|
isConnectionRestricted,
|
|
@@ -11,6 +11,7 @@ const mockIsOrientationCompatible = jest.fn(() => true);
|
|
|
11
11
|
jest.mock("react-native-safe-area-context", () => ({
|
|
12
12
|
...jest.requireActual("react-native-safe-area-context"),
|
|
13
13
|
useSafeAreaInsets: () => ({ top: 44 }),
|
|
14
|
+
useSafeAreaFrame: () => ({ x: 0, y: 0, width: 375, height: 812 }),
|
|
14
15
|
}));
|
|
15
16
|
|
|
16
17
|
jest.mock("../../RouteManager", () => ({
|
|
@@ -5,15 +5,85 @@ import {
|
|
|
5
5
|
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
|
|
6
6
|
import {
|
|
7
7
|
useCurrentScreenData,
|
|
8
|
-
useDimensions,
|
|
9
8
|
useRoute,
|
|
10
9
|
useIsTablet,
|
|
10
|
+
useIsScreenActive,
|
|
11
11
|
} from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
12
12
|
import { useMemo, useEffect, useState } from "react";
|
|
13
|
+
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
14
|
+
|
|
15
|
+
type MemoizedSafeAreaFrameWithActiveStateOptions = {
|
|
16
|
+
updateForInactiveScreens?: boolean;
|
|
17
|
+
isActive: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Base hook that wraps useSafeAreaFrame with memoization and inactive screen filtering.
|
|
22
|
+
* Requires isActive to be passed explicitly - use useMemoizedSafeAreaFrame for automatic detection.
|
|
23
|
+
*
|
|
24
|
+
* @param options.updateForInactiveScreens - If false, frame won't update when screen is inactive (default: true)
|
|
25
|
+
* @param options.isActive - Whether the screen is currently active
|
|
26
|
+
* @returns The memoized safe area frame { x, y, width, height }
|
|
27
|
+
*/
|
|
28
|
+
export const useMemoizedSafeAreaFrameWithActiveState = (
|
|
29
|
+
options: MemoizedSafeAreaFrameWithActiveStateOptions
|
|
30
|
+
) => {
|
|
31
|
+
const { updateForInactiveScreens = true, isActive } = options;
|
|
32
|
+
const frame = useSafeAreaFrame();
|
|
33
|
+
|
|
34
|
+
const [memoFrame, setMemoFrame] = useState(frame);
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const shouldUpdate = isActive || updateForInactiveScreens;
|
|
38
|
+
|
|
39
|
+
const dimensionsChanged =
|
|
40
|
+
frame.width !== memoFrame.width || frame.height !== memoFrame.height;
|
|
41
|
+
|
|
42
|
+
if (shouldUpdate && dimensionsChanged) {
|
|
43
|
+
setMemoFrame(frame);
|
|
44
|
+
}
|
|
45
|
+
}, [
|
|
46
|
+
frame.width,
|
|
47
|
+
frame.height,
|
|
48
|
+
isActive,
|
|
49
|
+
updateForInactiveScreens,
|
|
50
|
+
frame,
|
|
51
|
+
memoFrame.width,
|
|
52
|
+
memoFrame.height,
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
return memoFrame;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
type MemoizedSafeAreaFrameOptions = {
|
|
59
|
+
updateForInactiveScreens?: boolean;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Hook that wraps useSafeAreaFrame with memoization and inactive screen filtering.
|
|
64
|
+
* Uses useIsScreenActive() internally to determine active state - use useMemoizedSafeAreaFrameWithActiveState
|
|
65
|
+
* if you need to pass isActive explicitly.
|
|
66
|
+
*
|
|
67
|
+
* @param options.updateForInactiveScreens - If false, frame won't update when screen is inactive (default: true)
|
|
68
|
+
* @returns The memoized safe area frame { x, y, width, height }
|
|
69
|
+
*/
|
|
70
|
+
export const useMemoizedSafeAreaFrame = (
|
|
71
|
+
options: MemoizedSafeAreaFrameOptions = {}
|
|
72
|
+
) => {
|
|
73
|
+
const { updateForInactiveScreens = true } = options;
|
|
74
|
+
const isActive = useIsScreenActive();
|
|
75
|
+
|
|
76
|
+
return useMemoizedSafeAreaFrameWithActiveState({
|
|
77
|
+
updateForInactiveScreens,
|
|
78
|
+
isActive,
|
|
79
|
+
});
|
|
80
|
+
};
|
|
13
81
|
|
|
14
82
|
export const useWaitForValidOrientation = () => {
|
|
15
|
-
|
|
16
|
-
|
|
83
|
+
// Use memoized safe area frame to synchronize with Scene's dimension source
|
|
84
|
+
// This prevents race conditions where the orientation check passes before
|
|
85
|
+
// Scene's memoFrame has updated to the new dimensions
|
|
86
|
+
const { width: screenWidth, height } = useMemoizedSafeAreaFrame({
|
|
17
87
|
updateForInactiveScreens: false,
|
|
18
88
|
});
|
|
19
89
|
|
|
@@ -92,7 +92,13 @@ export function Screen(_props: Props) {
|
|
|
92
92
|
const isActive = useIsScreenActive();
|
|
93
93
|
|
|
94
94
|
const ref = React.useRef(null);
|
|
95
|
-
const
|
|
95
|
+
const isOrientationReady = useWaitForValidOrientation();
|
|
96
|
+
|
|
97
|
+
// Playable screens handle their own orientation via the native player plugin,
|
|
98
|
+
// so we skip the orientation wait gate to avoid a deadlock where the screen
|
|
99
|
+
// waits for landscape but blocks rendering that would trigger the rotation.
|
|
100
|
+
const isPlayableRoute = pathname?.includes("/playable");
|
|
101
|
+
const isReady = isOrientationReady || isPlayableRoute;
|
|
96
102
|
|
|
97
103
|
React.useEffect(() => {
|
|
98
104
|
if (ref.current && isActive && isReady) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { equals } from "ramda";
|
|
3
3
|
import { Animated, ViewProps, ViewStyle } from "react-native";
|
|
4
|
-
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
5
4
|
|
|
6
5
|
import { useScreenOrientationHandler } from "@applicaster/zapp-react-native-ui-components/Components/Screen/orientationHandler";
|
|
6
|
+
import { useMemoizedSafeAreaFrameWithActiveState } from "@applicaster/zapp-react-native-ui-components/Components/Screen/hooks";
|
|
7
7
|
|
|
8
8
|
import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
9
9
|
import { ScreenDataContext } from "../../Contexts/ScreenDataContext";
|
|
@@ -94,19 +94,13 @@ function SceneComponent({
|
|
|
94
94
|
isActive,
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
oldFrame.width === frame.width && oldFrame.height === frame.height
|
|
105
|
-
? oldFrame
|
|
106
|
-
: frame
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
}, [isActive, frame.width, frame.height]);
|
|
97
|
+
// Use shared memoized frame hook - synchronized with useWaitForValidOrientation
|
|
98
|
+
// to prevent race conditions during orientation changes
|
|
99
|
+
// Pass isActive from props since Scene knows its active state from Transitioner
|
|
100
|
+
const memoFrame = useMemoizedSafeAreaFrameWithActiveState({
|
|
101
|
+
updateForInactiveScreens: false,
|
|
102
|
+
isActive,
|
|
103
|
+
});
|
|
110
104
|
|
|
111
105
|
const isAnimating = animating && overlayStyle;
|
|
112
106
|
|
|
@@ -32,7 +32,7 @@ function getTestDimensions(testDimensions) {
|
|
|
32
32
|
return (process.env.NODE_ENV === "test" && testDimensions) || null;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
function ViewportAwareComponent(props: Props,
|
|
35
|
+
function ViewportAwareComponent(props: Props, forwardedRef) {
|
|
36
36
|
const viewportEvents = useViewportEventsContext();
|
|
37
37
|
|
|
38
38
|
const {
|
|
@@ -47,13 +47,22 @@ function ViewportAwareComponent(props: Props, ref) {
|
|
|
47
47
|
getTestDimensions(testDimensions) || initialDimensions
|
|
48
48
|
);
|
|
49
49
|
|
|
50
|
+
const localRef = React.useRef(null);
|
|
51
|
+
|
|
50
52
|
const [viewportChangeEvent, setViewportChangeEvent] = React.useState(null);
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
const assignRef = React.useCallback(
|
|
55
|
+
(_ref) => {
|
|
56
|
+
localRef.current = _ref;
|
|
57
|
+
|
|
58
|
+
if (typeof forwardedRef === "function") {
|
|
59
|
+
forwardedRef(_ref);
|
|
60
|
+
} else if (forwardedRef) {
|
|
61
|
+
forwardedRef.current = _ref;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
[forwardedRef]
|
|
65
|
+
);
|
|
57
66
|
|
|
58
67
|
const checkInViewport = (viewportChangeEvent, layoutEvent) => {
|
|
59
68
|
const inVerticalViewport = Utils.isInViewport(
|
|
@@ -94,7 +103,7 @@ function ViewportAwareComponent(props: Props, ref) {
|
|
|
94
103
|
const onViewportChange = (viewportChangeEvent) => {
|
|
95
104
|
setViewportChangeEvent(viewportChangeEvent);
|
|
96
105
|
|
|
97
|
-
const nodeHandle = findNodeHandle(
|
|
106
|
+
const nodeHandle = findNodeHandle(localRef.current);
|
|
98
107
|
|
|
99
108
|
if (!nodeHandle) {
|
|
100
109
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "15.0.0-alpha.
|
|
3
|
+
"version": "15.0.0-alpha.2210182446",
|
|
4
4
|
"description": "Applicaster Zapp React Native ui components for the Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "15.0.0-alpha.
|
|
32
|
-
"@applicaster/zapp-react-native-bridge": "15.0.0-alpha.
|
|
33
|
-
"@applicaster/zapp-react-native-redux": "15.0.0-alpha.
|
|
34
|
-
"@applicaster/zapp-react-native-utils": "15.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "15.0.0-alpha.2210182446",
|
|
32
|
+
"@applicaster/zapp-react-native-bridge": "15.0.0-alpha.2210182446",
|
|
33
|
+
"@applicaster/zapp-react-native-redux": "15.0.0-alpha.2210182446",
|
|
34
|
+
"@applicaster/zapp-react-native-utils": "15.0.0-alpha.2210182446",
|
|
35
35
|
"fast-json-stable-stringify": "^2.1.0",
|
|
36
36
|
"promise": "^8.3.0",
|
|
37
37
|
"url": "^0.11.0",
|