@applicaster/zapp-react-native-ui-components 16.0.0-alpha.1042942411 → 16.0.0-alpha.1054344748
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/AudioPlayer/tv/__tests__/audioPlayer.test.js +19 -0
- package/Components/AudioPlayer/tv/__tests__/index.test.tsx +120 -0
- package/Components/AudioPlayer/tv/index.tsx +5 -1
- package/Components/Cell/Cell.tsx +3 -6
- package/Components/Cell/TvOSCellComponent.tsx +0 -1
- package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +15 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/skipExpression.test.ts +294 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +64 -0
- package/Components/GeneralContentScreen/hookAdapter/skipExpression.ts +252 -0
- package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +18 -0
- package/Components/LinkHandler/LinkHandler.tsx +2 -7
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +64 -28
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +19 -4
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +43 -1
- package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +46 -217
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +109 -46
- package/Components/MasterCell/DefaultComponents/Button.tsx +44 -50
- package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +14 -13
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
- package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -3
- package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +50 -46
- package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +39 -47
- package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +6 -19
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +15 -45
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +36 -14
- package/Components/MasterCell/DefaultComponents/__tests__/Toggle.test.tsx +167 -0
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +67 -196
- package/Components/MasterCell/DefaultComponents/index.ts +0 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +6 -4
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/factory.test.ts +32 -0
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -2
- package/Components/MasterCell/elementMapper.tsx +0 -2
- package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +56 -0
- package/Components/ModalComponent/ActionsBottomSheet/__tests__/openActionsBottomSheet.test.ts +38 -0
- package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +24 -0
- package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
- package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +61 -0
- package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +87 -97
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +87 -126
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +140 -83
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +252 -123
- package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +205 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/Item.test.tsx +113 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
- package/Components/ModalComponent/AudioPlayer/Components/index.ts +3 -3
- package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +356 -0
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +521 -0
- package/Components/ModalComponent/BottomSheetModalContent.tsx +498 -66
- package/Components/ModalComponent/Button/index.tsx +5 -3
- package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
- package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
- package/Components/ModalComponent/Header/index.tsx +20 -7
- package/Components/ModalComponent/Header/utils.ts +1 -1
- package/Components/ModalComponent/ModalBlocksStyleContext.tsx +10 -0
- package/Components/ModalComponent/SortableList.tsx +156 -0
- package/Components/ModalComponent/SortableList.web.tsx +34 -0
- package/Components/ModalComponent/TextInputContent.tsx +135 -0
- package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +343 -0
- package/Components/ModalComponent/__tests__/SortableList.web.test.tsx +16 -0
- package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +169 -0
- package/Components/ModalComponent/__tests__/showTextInput.test.ts +95 -0
- package/Components/ModalComponent/index.tsx +18 -9
- package/Components/ModalComponent/presets/__tests__/getCell.test.ts +90 -0
- package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +78 -0
- package/Components/ModalComponent/presets/index.ts +27 -0
- package/Components/ModalComponent/presets/selectableCell.tsx +28 -0
- package/Components/ModalComponent/presets/standardCell.tsx +41 -0
- package/Components/ModalComponent/presets/types.ts +35 -0
- package/Components/ModalComponent/showTextInput.ts +52 -0
- package/Components/ModalComponent/utils.ts +82 -21
- package/Components/OfflineHandler/__tests__/index.test.tsx +109 -0
- package/Components/OfflineHandler/hooks.ts +0 -12
- package/Components/OfflineHandler/index.tsx +42 -4
- package/Components/PlayerContainer/PlayerContainer.tsx +19 -8
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -4
- package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +66 -13
- package/Components/River/ComponentsMap/ComponentsMap.tsx +85 -59
- package/Components/River/River.tsx +4 -0
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +138 -75
- package/Components/River/__tests__/componentsMap.test.js +8 -3
- package/Components/River/__tests__/resultCallback.test.tsx +47 -0
- package/Components/Screen/__tests__/Screen.test.tsx +24 -0
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
- package/Components/Screen/index.tsx +5 -0
- package/Components/Screen/navigationHandler.ts +8 -8
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +18 -2
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +36 -0
- package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +56 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +21 -4
- package/Components/Transitioner/AnimationManager.js +1 -1
- package/Components/Transitioner/Scene.tsx +4 -3
- package/Components/Transitioner/Transitioner.tsx +71 -33
- package/Components/Transitioner/__tests__/transitioner.test.js +372 -3
- package/Components/VideoLive/LiveImageManager.ts +9 -3
- package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
- package/Contexts/ModalNavigationContext/__tests__/index.test.tsx +15 -0
- package/Contexts/ModalNavigationContext/index.tsx +2 -2
- package/Hooks/useEntryActionsExpander.ts +63 -0
- package/assets/empty-Info.png +0 -0
- package/package.json +6 -5
- package/Components/MasterCell/DefaultComponents/CellBadge/__tests__/__snapshots__/index.test.tsx.snap +0 -18
- package/Components/MasterCell/DefaultComponents/CellBadge/__tests__/index.test.tsx +0 -90
- package/Components/MasterCell/DefaultComponents/UIKitAdapters/Badge.tsx +0 -49
- package/Components/MasterCell/DefaultComponents/__tests__/ActionButton.test.tsx +0 -122
- package/Components/MasterCell/DefaultComponents/__tests__/Button.test.tsx +0 -186
- package/Components/MasterCell/DefaultComponents/__tests__/DynamicBadge.test.tsx +0 -156
- package/Components/MasterCell/DefaultComponents/__tests__/__snapshots__/ActionButton.test.tsx.snap +0 -60
- package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +0 -332
- /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
|
@@ -1,15 +1,85 @@
|
|
|
1
|
-
import {
|
|
2
|
-
toFiniteNumberWithDefault,
|
|
3
|
-
toNumber,
|
|
4
|
-
} from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
1
|
+
import { toFiniteNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
5
2
|
import { isNil } from "ramda";
|
|
3
|
+
import { coreLogger } from "@applicaster/zapp-react-native-utils/logger";
|
|
6
4
|
|
|
7
|
-
const
|
|
5
|
+
const imageResizingLogger = coreLogger
|
|
6
|
+
?.addSubsystem("components")
|
|
7
|
+
?.addSubsystem("ImageResizing");
|
|
8
8
|
|
|
9
|
+
const TEMPLATE_REGEX = /{{(width|height)}}/gi;
|
|
10
|
+
const UNRESOLVED_PLACEHOLDER_REGEX = /{{[^}]*}}?/;
|
|
11
|
+
const INVALID_PLACEHOLDER_EXTRACT_REGEX = /{{([^}]*)}}?/g;
|
|
12
|
+
const ALLOWED_PLACEHOLDERS = ["width", "height"];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Merges query-param string `paramsString` into `baseUrl`.
|
|
16
|
+
* Params from `paramsString` override any existing params with the same key.
|
|
17
|
+
*/
|
|
18
|
+
export const mergeQueryParams = (
|
|
19
|
+
baseUrl: string,
|
|
20
|
+
paramsString: string
|
|
21
|
+
): string => {
|
|
22
|
+
try {
|
|
23
|
+
const urlObj = new URL(baseUrl);
|
|
24
|
+
const newParams = new URLSearchParams(paramsString);
|
|
25
|
+
|
|
26
|
+
newParams.forEach((value, key) => {
|
|
27
|
+
urlObj.searchParams.set(key, value);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return urlObj.toString();
|
|
31
|
+
} catch {
|
|
32
|
+
// If URL parsing fails, return original
|
|
33
|
+
return baseUrl;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Extracts unresolved placeholder names from a param pair and logs a warning.
|
|
39
|
+
*/
|
|
40
|
+
const logInvalidPlaceholders = (pair: string): void => {
|
|
41
|
+
const invalidNames: string[] = [];
|
|
42
|
+
let match: RegExpExecArray | null;
|
|
43
|
+
|
|
44
|
+
// Reset lastIndex before using the global regex
|
|
45
|
+
INVALID_PLACEHOLDER_EXTRACT_REGEX.lastIndex = 0;
|
|
46
|
+
|
|
47
|
+
while ((match = INVALID_PLACEHOLDER_EXTRACT_REGEX.exec(pair)) !== null) {
|
|
48
|
+
const name = match[1];
|
|
49
|
+
|
|
50
|
+
if (!ALLOWED_PLACEHOLDERS.includes(name?.toLowerCase())) {
|
|
51
|
+
invalidNames.push(name);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (invalidNames.length > 0) {
|
|
56
|
+
imageResizingLogger?.warning({
|
|
57
|
+
message: `Image resizing: invalid placeholder(s) found: ${invalidNames.map((n) => `{{${n}}}`).join(", ")}. Allowed placeholders are: {{width}}, {{height}}. The param "${pair}" was ignored.`,
|
|
58
|
+
data: { pair, invalidNames, allowedPlaceholders: ALLOWED_PLACEHOLDERS },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Parses a dimension mapping template string (query param format) and injects
|
|
65
|
+
* the resolved width/height values into the given URL.
|
|
66
|
+
*
|
|
67
|
+
* The template uses `{{width}}` and `{{height}}` placeholders.
|
|
68
|
+
* It is treated as query-param key=value pairs (e.g. "w={{width}}&h={{height}}"
|
|
69
|
+
* or "size={{width}}x{{height}}").
|
|
70
|
+
*
|
|
71
|
+
* Resolved params are **merged** into the original URL – existing params with
|
|
72
|
+
* the same key are replaced; new ones are appended.
|
|
73
|
+
*
|
|
74
|
+
* Invalid mappings (containing unresolved placeholders like `{{heit}}` or
|
|
75
|
+
* malformed `{{heit}`) are silently dropped and logged as warnings.
|
|
76
|
+
* A leading `?` in the template is stripped.
|
|
77
|
+
*/
|
|
9
78
|
export const withDimensions = (
|
|
10
79
|
url: Option<string>,
|
|
11
80
|
width: Option<number | string>,
|
|
12
|
-
height: Option<number | string
|
|
81
|
+
height: Option<number | string>,
|
|
82
|
+
dimensionMappingTemplate?: Option<string>
|
|
13
83
|
) => {
|
|
14
84
|
if (isNil(url)) {
|
|
15
85
|
return url;
|
|
@@ -22,23 +92,48 @@ export const withDimensions = (
|
|
|
22
92
|
const newWidth = Math.trunc(toFiniteNumberWithDefault(0, width));
|
|
23
93
|
const newHeight = Math.trunc(toFiniteNumberWithDefault(0, height));
|
|
24
94
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
95
|
+
if (newWidth <= 0 && newHeight <= 0) {
|
|
96
|
+
return url;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Strip leading `?` and whitespace from the template
|
|
100
|
+
const template = dimensionMappingTemplate?.trim()?.replace(/^\?/, "");
|
|
28
101
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
102
|
+
if (!template) {
|
|
103
|
+
return url;
|
|
104
|
+
}
|
|
33
105
|
|
|
34
|
-
|
|
35
|
-
|
|
106
|
+
// Replace {{width}} / {{height}} placeholders in the template
|
|
107
|
+
const resolvedTemplate = template.replace(TEMPLATE_REGEX, (_match, name) => {
|
|
108
|
+
if (name.toLowerCase() === "width") {
|
|
109
|
+
return newWidth > 0 ? String(newWidth) : _match;
|
|
110
|
+
}
|
|
36
111
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
112
|
+
if (name.toLowerCase() === "height") {
|
|
113
|
+
return newHeight > 0 ? String(newHeight) : _match;
|
|
40
114
|
}
|
|
41
115
|
|
|
42
|
-
return
|
|
116
|
+
return _match;
|
|
43
117
|
});
|
|
118
|
+
|
|
119
|
+
// Filter out param pairs that still contain unresolved / malformed placeholders
|
|
120
|
+
const cleanedParams = resolvedTemplate
|
|
121
|
+
.split("&")
|
|
122
|
+
.filter((pair) => {
|
|
123
|
+
if (UNRESOLVED_PLACEHOLDER_REGEX.test(pair)) {
|
|
124
|
+
logInvalidPlaceholders(pair);
|
|
125
|
+
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return true;
|
|
130
|
+
})
|
|
131
|
+
.join("&");
|
|
132
|
+
|
|
133
|
+
if (!cleanedParams) {
|
|
134
|
+
return url;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Parse the resolved template as query params and merge into URL
|
|
138
|
+
return mergeQueryParams(url, cleanedParams);
|
|
44
139
|
};
|
|
@@ -14,25 +14,36 @@ type Style = {
|
|
|
14
14
|
height: Option<number | string>;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
const withAppliedDimensions =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const withAppliedDimensions =
|
|
18
|
+
(style: Style, dimensionMappingTemplate: string) => (source: Source) => ({
|
|
19
|
+
...source,
|
|
20
|
+
uri: withDimensions(
|
|
21
|
+
source?.uri,
|
|
22
|
+
style?.width,
|
|
23
|
+
style?.height,
|
|
24
|
+
dimensionMappingTemplate
|
|
25
|
+
),
|
|
26
|
+
});
|
|
21
27
|
|
|
22
28
|
export const withDimensionsHOC = (Component) => {
|
|
23
29
|
return function WithDimensions(props: Record<string, unknown>) {
|
|
24
30
|
const theme = useTheme<BaseThemePropertiesMobile>();
|
|
25
31
|
|
|
26
|
-
const
|
|
27
|
-
theme.use_downscaling_images
|
|
32
|
+
const useImageResizing = toBooleanWithDefaultFalse(
|
|
33
|
+
theme.use_image_resizing ?? theme.use_downscaling_images
|
|
28
34
|
);
|
|
29
35
|
|
|
36
|
+
const dimensionMappingTemplate = theme.image_resizing_template;
|
|
37
|
+
|
|
30
38
|
return (
|
|
31
39
|
<Component
|
|
32
40
|
{...props}
|
|
33
41
|
withDimensions={
|
|
34
|
-
|
|
35
|
-
? withAppliedDimensions(
|
|
42
|
+
useImageResizing
|
|
43
|
+
? withAppliedDimensions(
|
|
44
|
+
(props?.style || {}) as Style,
|
|
45
|
+
dimensionMappingTemplate
|
|
46
|
+
)
|
|
36
47
|
: identity
|
|
37
48
|
}
|
|
38
49
|
/>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
1
|
+
import { getPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
3
2
|
import { loggerLiveImageManager } from "../../../VideoLive/loggerHelper";
|
|
4
3
|
|
|
5
4
|
const { log_debug, log_error } = loggerLiveImageManager;
|
|
@@ -74,10 +73,9 @@ export async function executePreloadHooks({
|
|
|
74
73
|
let payload: any = entry;
|
|
75
74
|
|
|
76
75
|
let needsAbort = false;
|
|
77
|
-
const plugins = appStore.get("plugins");
|
|
78
76
|
|
|
79
77
|
for (const hookConfig of sortedHooks) {
|
|
80
|
-
const plugin =
|
|
78
|
+
const plugin = getPluginByIdentifier(hookConfig.identifier, true);
|
|
81
79
|
|
|
82
80
|
if (!plugin?.module) {
|
|
83
81
|
log_debug(
|
|
@@ -8,7 +8,7 @@ import Image from "../Image";
|
|
|
8
8
|
import { useTrackCurrentAutoScrollingElement } from "@applicaster/zapp-react-native-utils/reactHooks/autoscrolling/useTrackCurrentAutoScrollingElement";
|
|
9
9
|
import { useUIComponentContext } from "@applicaster/zapp-react-native-ui-components/Contexts/UIComponentContext";
|
|
10
10
|
import { getPropComponentType } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
11
|
-
import {
|
|
11
|
+
import { getPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
12
12
|
import { useAccessibilityState } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
|
|
13
13
|
|
|
14
14
|
type LiveImageProps = {
|
|
@@ -249,9 +249,8 @@ const LiveImageComponent = (props: LiveImageProps) => {
|
|
|
249
249
|
getPlayerConfig(player_screen_id, actionIdentifier) ?? {};
|
|
250
250
|
|
|
251
251
|
const playableEntry = playerPluginId ? getPlayableEntry(item) : null;
|
|
252
|
-
const plugins = appStore.get("plugins");
|
|
253
252
|
|
|
254
|
-
const playerPlugin =
|
|
253
|
+
const playerPlugin = getPluginByIdentifier(playerPluginId);
|
|
255
254
|
|
|
256
255
|
const isShouldRender =
|
|
257
256
|
playerPlugin &&
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { isNil } from "ramda";
|
|
3
|
-
import {
|
|
3
|
+
import { ImageStyle, View } from "react-native";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
FIT_POSITION,
|
|
6
|
+
IMAGE_SIZING_FILL,
|
|
7
|
+
IMAGE_SIZING_FIT,
|
|
8
|
+
} from "@applicaster/zapp-react-native-utils/manifestUtils/secondaryImage";
|
|
9
|
+
import { QBImage as Image } from "@applicaster/zapp-react-native-ui-components/Components/Image";
|
|
8
10
|
|
|
9
11
|
import { useGetImageDimensions } from "./hooks";
|
|
10
12
|
import {
|
|
11
13
|
DisplayMode,
|
|
12
|
-
|
|
13
|
-
ImageSizing,
|
|
14
|
+
getStyle,
|
|
14
15
|
isDisplayModeFixed,
|
|
15
16
|
isImageSizingFit,
|
|
16
17
|
} from "./utils";
|
|
@@ -19,9 +20,9 @@ import { withAsyncRenderHOC } from "../../hoc/withAsyncRender";
|
|
|
19
20
|
interface Props {
|
|
20
21
|
displayMode: DisplayMode;
|
|
21
22
|
uri: Nullable<string>;
|
|
22
|
-
style:
|
|
23
|
-
imageSizing:
|
|
24
|
-
fitPosition:
|
|
23
|
+
style: ImageStyle;
|
|
24
|
+
imageSizing: typeof IMAGE_SIZING_FIT | typeof IMAGE_SIZING_FILL;
|
|
25
|
+
fitPosition: typeof FIT_POSITION;
|
|
25
26
|
fixedWidth: number;
|
|
26
27
|
fixedHeight: number;
|
|
27
28
|
onAsyncRender?: () => void;
|
|
@@ -30,17 +31,8 @@ interface Props {
|
|
|
30
31
|
/** Secondary Image Dynamic does not render until the image is loaded */
|
|
31
32
|
const SecondaryImageDynamic = withAsyncRenderHOC(
|
|
32
33
|
(props: Props & { onAsyncRender: () => void }) => {
|
|
33
|
-
const {
|
|
34
|
-
|
|
35
|
-
style,
|
|
36
|
-
displayMode,
|
|
37
|
-
imageSizing,
|
|
38
|
-
fitPosition,
|
|
39
|
-
onAsyncRender,
|
|
40
|
-
fixedHeight: _fixedHeight,
|
|
41
|
-
fixedWidth: _fixedWidth,
|
|
42
|
-
...imageProps
|
|
43
|
-
} = props;
|
|
34
|
+
const { uri, style, displayMode, imageSizing, fitPosition, onAsyncRender } =
|
|
35
|
+
props;
|
|
44
36
|
|
|
45
37
|
const imageDimension = useGetImageDimensions(
|
|
46
38
|
uri,
|
|
@@ -57,18 +49,24 @@ const SecondaryImageDynamic = withAsyncRenderHOC(
|
|
|
57
49
|
}
|
|
58
50
|
|
|
59
51
|
return (
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
52
|
+
<View style={style} onLayout={onAsyncRender}>
|
|
53
|
+
<Image
|
|
54
|
+
{...props}
|
|
55
|
+
source={{ uri }}
|
|
56
|
+
style={{
|
|
57
|
+
...getStyle({
|
|
58
|
+
imageSizing,
|
|
59
|
+
fitPosition,
|
|
60
|
+
displayMode,
|
|
61
|
+
imageDimension,
|
|
62
|
+
containerHeight,
|
|
63
|
+
containerWidth,
|
|
64
|
+
}),
|
|
65
|
+
borderRadius: style.borderRadius,
|
|
66
|
+
aspectRatio: imageDimension.aspectRatio,
|
|
67
|
+
}}
|
|
68
|
+
/>
|
|
69
|
+
</View>
|
|
72
70
|
);
|
|
73
71
|
}
|
|
74
72
|
);
|
|
@@ -83,8 +81,6 @@ const SecondaryImageFixed = (props: Props) => {
|
|
|
83
81
|
fitPosition,
|
|
84
82
|
fixedHeight,
|
|
85
83
|
fixedWidth,
|
|
86
|
-
onAsyncRender: _onAsyncRender,
|
|
87
|
-
...imageProps
|
|
88
84
|
} = props;
|
|
89
85
|
|
|
90
86
|
const imageDimension = useGetImageDimensions(
|
|
@@ -94,18 +90,26 @@ const SecondaryImageFixed = (props: Props) => {
|
|
|
94
90
|
);
|
|
95
91
|
|
|
96
92
|
return (
|
|
97
|
-
<
|
|
98
|
-
{
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
93
|
+
<View style={style}>
|
|
94
|
+
{isNil(imageDimension?.aspectRatio) ? null : (
|
|
95
|
+
<Image
|
|
96
|
+
{...props}
|
|
97
|
+
source={{ uri }}
|
|
98
|
+
style={{
|
|
99
|
+
...getStyle({
|
|
100
|
+
imageSizing,
|
|
101
|
+
fitPosition,
|
|
102
|
+
displayMode,
|
|
103
|
+
imageDimension,
|
|
104
|
+
containerHeight: fixedHeight,
|
|
105
|
+
containerWidth: fixedWidth,
|
|
106
|
+
}),
|
|
107
|
+
borderRadius: style.borderRadius,
|
|
108
|
+
aspectRatio: imageDimension.aspectRatio,
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
)}
|
|
112
|
+
</View>
|
|
109
113
|
);
|
|
110
114
|
};
|
|
111
115
|
|
|
@@ -3,21 +3,19 @@
|
|
|
3
3
|
exports[`SecondaryImage - Image SecondaryImage fixed mode should not use async render props 1`] = `
|
|
4
4
|
<View
|
|
5
5
|
style={
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"height": 100,
|
|
14
|
-
"width": 100,
|
|
15
|
-
},
|
|
16
|
-
]
|
|
6
|
+
{
|
|
7
|
+
"borderRadius": 10,
|
|
8
|
+
"height": 100,
|
|
9
|
+
"width": 100,
|
|
10
|
+
}
|
|
17
11
|
}
|
|
18
|
-
testID="secondary-image-fixed"
|
|
19
12
|
>
|
|
20
13
|
<Image
|
|
14
|
+
displayMode="fixed"
|
|
15
|
+
fitPosition="center"
|
|
16
|
+
fixedHeight={100}
|
|
17
|
+
fixedWidth={100}
|
|
18
|
+
imageSizing="fill"
|
|
21
19
|
source={
|
|
22
20
|
{
|
|
23
21
|
"uri": "someUrl",
|
|
@@ -31,6 +29,7 @@ exports[`SecondaryImage - Image SecondaryImage fixed mode should not use async r
|
|
|
31
29
|
"width": 100,
|
|
32
30
|
}
|
|
33
31
|
}
|
|
32
|
+
uri="someUrl"
|
|
34
33
|
/>
|
|
35
34
|
</View>
|
|
36
35
|
`;
|
|
@@ -45,20 +44,20 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
|
|
|
45
44
|
<View
|
|
46
45
|
onLayout={[Function]}
|
|
47
46
|
style={
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"height": 100,
|
|
56
|
-
"width": 100,
|
|
57
|
-
},
|
|
58
|
-
]
|
|
47
|
+
{
|
|
48
|
+
"borderRadius": 10,
|
|
49
|
+
"height": 100,
|
|
50
|
+
"width": 100,
|
|
51
|
+
}
|
|
59
52
|
}
|
|
60
53
|
>
|
|
61
54
|
<Image
|
|
55
|
+
displayMode="dynamic"
|
|
56
|
+
fitPosition="center"
|
|
57
|
+
fixedHeight={0}
|
|
58
|
+
fixedWidth={0}
|
|
59
|
+
imageSizing="fill"
|
|
60
|
+
onAsyncRender={[Function]}
|
|
62
61
|
source={
|
|
63
62
|
{
|
|
64
63
|
"uri": "someUrl",
|
|
@@ -72,6 +71,7 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
|
|
|
72
71
|
"width": 100,
|
|
73
72
|
}
|
|
74
73
|
}
|
|
74
|
+
uri="someUrl"
|
|
75
75
|
/>
|
|
76
76
|
</View>
|
|
77
77
|
`;
|
|
@@ -79,21 +79,19 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
|
|
|
79
79
|
exports[`SecondaryImage - Image SecondaryImage should render in fixed mode with known dimensions 1`] = `
|
|
80
80
|
<View
|
|
81
81
|
style={
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
"height": 100,
|
|
90
|
-
"width": 100,
|
|
91
|
-
},
|
|
92
|
-
]
|
|
82
|
+
{
|
|
83
|
+
"borderRadius": 10,
|
|
84
|
+
"height": 100,
|
|
85
|
+
"width": 100,
|
|
86
|
+
}
|
|
93
87
|
}
|
|
94
|
-
testID="secondary-image-fixed"
|
|
95
88
|
>
|
|
96
89
|
<Image
|
|
90
|
+
displayMode="fixed"
|
|
91
|
+
fitPosition="center"
|
|
92
|
+
fixedHeight={100}
|
|
93
|
+
fixedWidth={100}
|
|
94
|
+
imageSizing="fill"
|
|
97
95
|
source={
|
|
98
96
|
{
|
|
99
97
|
"uri": "someUrl",
|
|
@@ -107,6 +105,7 @@ exports[`SecondaryImage - Image SecondaryImage should render in fixed mode with
|
|
|
107
105
|
"width": 100,
|
|
108
106
|
}
|
|
109
107
|
}
|
|
108
|
+
uri="someUrl"
|
|
110
109
|
/>
|
|
111
110
|
</View>
|
|
112
111
|
`;
|
|
@@ -114,18 +113,11 @@ exports[`SecondaryImage - Image SecondaryImage should render in fixed mode with
|
|
|
114
113
|
exports[`SecondaryImage - Image SecondaryImage should render in fixed mode without image until loaded 1`] = `
|
|
115
114
|
<View
|
|
116
115
|
style={
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"height": 100,
|
|
125
|
-
"width": 100,
|
|
126
|
-
},
|
|
127
|
-
]
|
|
116
|
+
{
|
|
117
|
+
"borderRadius": 5,
|
|
118
|
+
"height": 100,
|
|
119
|
+
"width": 100,
|
|
120
|
+
}
|
|
128
121
|
}
|
|
129
|
-
testID="secondary-image-fixed"
|
|
130
122
|
/>
|
|
131
123
|
`;
|
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
import { identity, isNil } from "ramda";
|
|
2
2
|
import {
|
|
3
3
|
POSITION_OVER_IMAGE,
|
|
4
|
+
DISPLAY_MODE_DYNAMIC,
|
|
4
5
|
DISPLAY_MODE_FIXED,
|
|
5
6
|
VISIBILITY_ALWAYS,
|
|
6
7
|
VISIBILITY_DEFAULT,
|
|
7
8
|
VISIBILITY_FOCUSED,
|
|
8
9
|
IMAGE_POSITION,
|
|
9
10
|
IMAGE_SIZING_FIT,
|
|
11
|
+
IMAGE_SIZING_FILL,
|
|
10
12
|
FIT_POSITION,
|
|
11
13
|
} from "@applicaster/zapp-react-native-utils/manifestUtils/secondaryImage";
|
|
12
14
|
import { ImageStyle } from "react-native";
|
|
13
|
-
import type {
|
|
14
|
-
SecondaryImageDisplayMode,
|
|
15
|
-
SecondaryImageFitPosition,
|
|
16
|
-
SecondaryImageImageSizing,
|
|
17
|
-
} from "@applicaster/uikit/lib/components/uikit/secondary-image/types";
|
|
18
15
|
|
|
19
16
|
const SECONDARY_IMAGE_PREFIX = "secondary_image";
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export type FitPosition = SecondaryImageFitPosition;
|
|
18
|
+
type ImageSizing = typeof IMAGE_SIZING_FIT | typeof IMAGE_SIZING_FILL;
|
|
24
19
|
|
|
25
20
|
type ImagePosition = (typeof IMAGE_POSITION)[keyof typeof IMAGE_POSITION];
|
|
26
21
|
|
|
27
|
-
export type DisplayMode =
|
|
22
|
+
export type DisplayMode =
|
|
23
|
+
| typeof DISPLAY_MODE_FIXED
|
|
24
|
+
| typeof DISPLAY_MODE_DYNAMIC;
|
|
28
25
|
|
|
29
26
|
export enum SecondaryImageStyleKeys {
|
|
30
27
|
ENABLE = "switch",
|
|
@@ -177,16 +174,6 @@ export const getStyle = ({
|
|
|
177
174
|
imageDimension,
|
|
178
175
|
containerWidth,
|
|
179
176
|
containerHeight,
|
|
180
|
-
}: {
|
|
181
|
-
imageSizing: ImageSizing;
|
|
182
|
-
fitPosition: FitPosition;
|
|
183
|
-
displayMode: DisplayMode;
|
|
184
|
-
imageDimension: {
|
|
185
|
-
width: number;
|
|
186
|
-
height: number;
|
|
187
|
-
};
|
|
188
|
-
containerWidth: number;
|
|
189
|
-
containerHeight: number;
|
|
190
177
|
}): ImageStyle => {
|
|
191
178
|
if (!isImageSizingFit(imageSizing)) {
|
|
192
179
|
return {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { Text } from "react-native";
|
|
3
|
+
import { omit } from "ramda";
|
|
2
4
|
import {
|
|
3
5
|
textTransform,
|
|
4
6
|
dateFormat,
|
|
5
7
|
} from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
6
|
-
import { Text as UIKitText } from "@applicaster/uikit/lib/components/uikit/text";
|
|
7
8
|
|
|
8
9
|
import { useTextLabel, withFocusedStyles } from "./hooks";
|
|
9
10
|
import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
@@ -19,18 +20,11 @@ type Props = {
|
|
|
19
20
|
entry?: any;
|
|
20
21
|
dateTransformEnabled: boolean;
|
|
21
22
|
dateTransform: string;
|
|
22
|
-
|
|
23
|
-
focusedStyles?: any;
|
|
24
|
-
normalStyles?: any;
|
|
25
|
-
numberOfLines?: number;
|
|
26
|
-
ellipsizeMode?: "head" | "middle" | "tail" | "clip";
|
|
27
|
-
testID?: string;
|
|
28
|
-
accessibilityLabel?: string;
|
|
29
|
-
accessibilityHint?: string;
|
|
30
|
-
nativeID?: string;
|
|
31
|
-
selectable?: boolean;
|
|
23
|
+
[key: string]: any;
|
|
32
24
|
};
|
|
33
25
|
|
|
26
|
+
const withoutLabel = omit(["label"]);
|
|
27
|
+
|
|
34
28
|
const _Text = ({
|
|
35
29
|
style,
|
|
36
30
|
label,
|
|
@@ -38,16 +32,7 @@ const _Text = ({
|
|
|
38
32
|
transformText = "default",
|
|
39
33
|
dateTransformEnabled = false,
|
|
40
34
|
dateTransform,
|
|
41
|
-
|
|
42
|
-
focusedStyles,
|
|
43
|
-
normalStyles,
|
|
44
|
-
numberOfLines,
|
|
45
|
-
ellipsizeMode,
|
|
46
|
-
testID,
|
|
47
|
-
accessibilityLabel,
|
|
48
|
-
accessibilityHint,
|
|
49
|
-
nativeID,
|
|
50
|
-
selectable,
|
|
35
|
+
...otherProps
|
|
51
36
|
}: Props) => {
|
|
52
37
|
const _label = useTextLabel({ label, entry });
|
|
53
38
|
const isMeasurement = React.useContext(MeasurementPortalContext);
|
|
@@ -57,8 +42,8 @@ const _Text = ({
|
|
|
57
42
|
|
|
58
43
|
// set maximum possible height for the text in case of measurement
|
|
59
44
|
const height =
|
|
60
|
-
isMeasurement && numberOfLines && style.lineHeight
|
|
61
|
-
? toNumber(numberOfLines) * toNumber(style.lineHeight)
|
|
45
|
+
isMeasurement && otherProps.numberOfLines && style.lineHeight
|
|
46
|
+
? toNumber(otherProps.numberOfLines) * toNumber(style.lineHeight)
|
|
62
47
|
: undefined;
|
|
63
48
|
|
|
64
49
|
const textLabel = dateTransformEnabled
|
|
@@ -67,7 +52,7 @@ const _Text = ({
|
|
|
67
52
|
|
|
68
53
|
React.useLayoutEffect(() => {
|
|
69
54
|
if (cellFocused) {
|
|
70
|
-
switch (state) {
|
|
55
|
+
switch (otherProps.state) {
|
|
71
56
|
case "focused":
|
|
72
57
|
accessibilityManager.addHeading(textLabel);
|
|
73
58
|
break;
|
|
@@ -76,35 +61,20 @@ const _Text = ({
|
|
|
76
61
|
break;
|
|
77
62
|
}
|
|
78
63
|
}
|
|
79
|
-
}, [
|
|
64
|
+
}, [cellFocused, otherProps.state, textLabel]);
|
|
80
65
|
|
|
81
66
|
if (isNilOrEmpty(_label)) {
|
|
82
67
|
return null;
|
|
83
68
|
}
|
|
84
69
|
|
|
85
70
|
return (
|
|
86
|
-
<
|
|
87
|
-
style={[
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
otherProps: {
|
|
91
|
-
state,
|
|
92
|
-
focusedStyles,
|
|
93
|
-
normalStyles,
|
|
94
|
-
},
|
|
95
|
-
}),
|
|
96
|
-
{ height },
|
|
97
|
-
]}
|
|
98
|
-
numberOfLines={numberOfLines}
|
|
99
|
-
ellipsizeMode={ellipsizeMode}
|
|
100
|
-
testID={testID}
|
|
101
|
-
accessibilityLabel={accessibilityLabel}
|
|
102
|
-
accessibilityHint={accessibilityHint}
|
|
103
|
-
nativeID={nativeID}
|
|
104
|
-
selectable={selectable}
|
|
71
|
+
<Text
|
|
72
|
+
style={[withFocusedStyles({ style, otherProps }), { height }]}
|
|
73
|
+
{...withoutLabel(otherProps)}
|
|
74
|
+
allowFontScaling={false}
|
|
105
75
|
>
|
|
106
76
|
{textLabel}
|
|
107
|
-
</
|
|
77
|
+
</Text>
|
|
108
78
|
);
|
|
109
79
|
};
|
|
110
80
|
|