@applicaster/zapp-react-native-ui-components 12.0.0-alpha.5786305091 → 12.0.0-alpha.5882013252
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.
|
@@ -1,3 +1,31 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from "react";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import FastImage, {
|
|
4
|
+
FastImageProps,
|
|
5
|
+
} from "@applicaster/react-native-fast-image";
|
|
6
|
+
|
|
7
|
+
export const QBImage = (props: FastImageProps) => {
|
|
8
|
+
const source = React.useMemo(() => {
|
|
9
|
+
if (typeof props.source === "number") {
|
|
10
|
+
return props.source;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
uri: props.source.uri,
|
|
15
|
+
headers: props.source.headers,
|
|
16
|
+
priority: props.source.priority,
|
|
17
|
+
cache: props.source.cache,
|
|
18
|
+
};
|
|
19
|
+
}, [
|
|
20
|
+
...(typeof props.source === "object"
|
|
21
|
+
? [
|
|
22
|
+
props.source?.uri,
|
|
23
|
+
props.source?.priority,
|
|
24
|
+
props.source?.cache,
|
|
25
|
+
props.source?.headers,
|
|
26
|
+
]
|
|
27
|
+
: []),
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
return <FastImage {...props} source={source} />;
|
|
31
|
+
};
|
|
@@ -1,43 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
import { View, StyleSheet, LayoutChangeEvent } from "react-native";
|
|
3
|
-
import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
|
|
1
|
+
/* eslint react/prop-types: off */
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
type LayoutDimensions = {
|
|
11
|
-
width: number;
|
|
12
|
-
height: number;
|
|
13
|
-
};
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { View, StyleSheet } from "react-native";
|
|
5
|
+
import * as R from "ramda";
|
|
6
|
+
import { v4 } from "uuid";
|
|
14
7
|
|
|
15
|
-
type
|
|
16
|
-
width: number;
|
|
17
|
-
height: number;
|
|
18
|
-
index?: number;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
type MeasurementsPortalProps = {
|
|
8
|
+
type Props = {
|
|
22
9
|
Component: React.ElementType;
|
|
23
|
-
onLayout: (
|
|
24
|
-
componentProps?: Record<
|
|
25
|
-
onLoadFinished?: () => void;
|
|
10
|
+
onLayout: (LayoutChangeEvent) => void;
|
|
11
|
+
componentProps?: Record<any, any>;
|
|
26
12
|
};
|
|
27
13
|
|
|
28
|
-
|
|
29
|
-
measureComponent: (
|
|
30
|
-
comp: React.ElementType,
|
|
31
|
-
props: Record<string, any>
|
|
32
|
-
) => Promise<MeasurementResult>;
|
|
33
|
-
measuringInProgress: boolean;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
type MeasurementsPortalContextProviderProps = {
|
|
37
|
-
children: ReactNode;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const isError = (possibleError: any): boolean => possibleError instanceof Error;
|
|
14
|
+
const isError = (possibleError): boolean => possibleError instanceof Error;
|
|
41
15
|
|
|
42
16
|
const styles = StyleSheet.create({
|
|
43
17
|
container: {
|
|
@@ -51,245 +25,100 @@ const styles = StyleSheet.create({
|
|
|
51
25
|
wrapper: {},
|
|
52
26
|
});
|
|
53
27
|
|
|
54
|
-
|
|
55
|
-
component: React.ElementType;
|
|
56
|
-
componentProps: Record<string, any> | null;
|
|
57
|
-
measureComponentCallback: ((result: MeasurementResult) => void) | null;
|
|
58
|
-
onLoadFinishedIsCalled: boolean;
|
|
59
|
-
measuringInProgress: boolean;
|
|
60
|
-
layout: LayoutDimensions;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
type Action =
|
|
64
|
-
| { type: "SET_COMPONENT"; payload: React.ElementType }
|
|
65
|
-
| { type: "SET_COMPONENT_PROPS"; payload: Record<string, any> | null }
|
|
66
|
-
| {
|
|
67
|
-
type: "SET_MEASURE_CALLBACK";
|
|
68
|
-
payload: ((result: MeasurementResult) => void) | null;
|
|
69
|
-
}
|
|
70
|
-
| { type: "SET_ON_LOAD_FINISHED"; payload: boolean }
|
|
71
|
-
| { type: "SET_MEASURING_PROGRESS"; payload: boolean }
|
|
72
|
-
| { type: "SET_LAYOUT"; payload: LayoutDimensions };
|
|
73
|
-
|
|
74
|
-
const MEASUREMENT_ACTIONS = {
|
|
75
|
-
setComponent: "SET_COMPONENT",
|
|
76
|
-
setComponentProps: "SET_COMPONENT_PROPS",
|
|
77
|
-
setMeasureCallback: "SET_MEASURE_CALLBACK",
|
|
78
|
-
setOnLoadFinished: "SET_ON_LOAD_FINISHED",
|
|
79
|
-
setMeasuringProgress: "SET_MEASURING_PROGRESS",
|
|
80
|
-
setLayout: "SET_LAYOUT",
|
|
81
|
-
} as const;
|
|
82
|
-
|
|
83
|
-
const reducer = (state: State, action: Action): State => {
|
|
84
|
-
switch (action.type) {
|
|
85
|
-
case MEASUREMENT_ACTIONS.setComponent:
|
|
86
|
-
return { ...state, component: action.payload };
|
|
87
|
-
case MEASUREMENT_ACTIONS.setComponentProps:
|
|
88
|
-
return { ...state, componentProps: action.payload };
|
|
89
|
-
case MEASUREMENT_ACTIONS.setMeasureCallback:
|
|
90
|
-
return { ...state, measureComponentCallback: action.payload };
|
|
91
|
-
case MEASUREMENT_ACTIONS.setOnLoadFinished:
|
|
92
|
-
return { ...state, onLoadFinishedIsCalled: action.payload };
|
|
93
|
-
case MEASUREMENT_ACTIONS.setMeasuringProgress:
|
|
94
|
-
return { ...state, measuringInProgress: action.payload };
|
|
95
|
-
case MEASUREMENT_ACTIONS.setLayout:
|
|
96
|
-
return { ...state, layout: action.payload };
|
|
97
|
-
default:
|
|
98
|
-
return state;
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const initialState: State = {
|
|
103
|
-
component: null,
|
|
104
|
-
componentProps: null,
|
|
105
|
-
measureComponentCallback: null,
|
|
106
|
-
onLoadFinishedIsCalled: false,
|
|
107
|
-
measuringInProgress: false,
|
|
108
|
-
layout: { width: 0, height: 0 },
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Handles layout changes for the MeasurementsPortal component
|
|
113
|
-
*/
|
|
114
|
-
const onLayout =
|
|
115
|
-
(dispatch) =>
|
|
116
|
-
({ nativeEvent: { layout: newLayout } }: LayoutChangeEvent) => {
|
|
117
|
-
log_debug("Rendered measurement layout", { newLayout });
|
|
118
|
-
dispatch({ type: MEASUREMENT_ACTIONS.setLayout, payload: newLayout });
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* MeasurementsPortal is a component that is used to measure the size of a component
|
|
123
|
-
* It is not rendered to the main tree, but it actually uses a component and its props to measure the size of the component.
|
|
124
|
-
* The <Component> comes from the measureComponent method of the MeasurementPortalContext.
|
|
125
|
-
*/
|
|
126
|
-
const MeasurementsPortal = ({
|
|
127
|
-
Component,
|
|
128
|
-
onLayout,
|
|
129
|
-
componentProps,
|
|
130
|
-
}: MeasurementsPortalProps) => {
|
|
131
|
-
if (!Component) {
|
|
132
|
-
return null;
|
|
133
|
-
}
|
|
134
|
-
|
|
28
|
+
const MeasurementsPortal = ({ Component, onLayout, componentProps }: Props) => {
|
|
135
29
|
return (
|
|
136
30
|
<View style={styles.container} testID="MeasurementsPortal">
|
|
137
|
-
<View style={styles.wrapper} onLayout={onLayout}>
|
|
31
|
+
<View style={styles.wrapper} onLayout={onLayout} key={v4()}>
|
|
138
32
|
<Component {...componentProps} />
|
|
139
33
|
</View>
|
|
140
34
|
</View>
|
|
141
35
|
);
|
|
142
36
|
};
|
|
143
37
|
|
|
144
|
-
const MeasurementPortalContext =
|
|
145
|
-
React.createContext<MeasurementPortalContextValue | null>(null);
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* The MeasurementsPortalContextProvider provides a measureComponent method, and a measuringInProgress flag
|
|
149
|
-
* With these we can pre-render a component and measure its size before rendering it to the main tree to avoid layout shifts
|
|
150
|
-
*/
|
|
151
|
-
const MeasurementsPortalContextProvider = ({
|
|
152
|
-
children,
|
|
153
|
-
}: MeasurementsPortalContextProviderProps) => {
|
|
154
|
-
const [state, dispatch] = useReducer(reducer, initialState);
|
|
155
|
-
|
|
156
|
-
const onLoadFinishedRef =
|
|
157
|
-
React.useRef<MeasurementsPortalProps["onLoadFinished"]>(null);
|
|
38
|
+
const MeasurementPortalContext = React.createContext(null);
|
|
158
39
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
*/
|
|
163
|
-
const finalize = useCallback(() => {
|
|
164
|
-
if (state.measureComponentCallback) {
|
|
165
|
-
log_debug("Finalize measurement process", {
|
|
166
|
-
layout: state.layout,
|
|
167
|
-
componentProps: state.componentProps,
|
|
168
|
-
});
|
|
40
|
+
const MeasurementsPortalContextProvider = ({ children }) => {
|
|
41
|
+
const Component = React.useRef(View);
|
|
42
|
+
const [measuringInProgress, setMeasuringInProgress] = React.useState(false);
|
|
169
43
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
index: state.componentProps?.index,
|
|
174
|
-
});
|
|
175
|
-
}
|
|
44
|
+
const measureComponentCallback = React.useRef(null);
|
|
45
|
+
const componentProps = React.useRef(null);
|
|
46
|
+
const onLoadFinishedIsCalled = React.useRef(null);
|
|
176
47
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
type: MEASUREMENT_ACTIONS.setMeasuringProgress,
|
|
181
|
-
payload: false,
|
|
182
|
-
});
|
|
48
|
+
const setComponent = (comp) => {
|
|
49
|
+
Component.current = comp;
|
|
50
|
+
};
|
|
183
51
|
|
|
184
|
-
|
|
185
|
-
|
|
52
|
+
const setMeasureComponentCallback = (cb) => {
|
|
53
|
+
measureComponentCallback.current = cb;
|
|
54
|
+
};
|
|
186
55
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
56
|
+
const finalize = ({ width, height }) => {
|
|
57
|
+
measureComponentCallback?.current?.({
|
|
58
|
+
width,
|
|
59
|
+
height,
|
|
60
|
+
index: componentProps.current.index,
|
|
192
61
|
});
|
|
193
62
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
onLoadFinishedRef.current
|
|
199
|
-
) {
|
|
200
|
-
finalize();
|
|
201
|
-
}
|
|
202
|
-
}, [state.measureComponentCallback, state.layout, finalize]);
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Utility function that takes, a component and its props, measures the rendered size of the component
|
|
206
|
-
* and creates a promise that does not get resolved with the measurement result (width/height/index)
|
|
207
|
-
* until the onLoadFinished callback is called
|
|
208
|
-
*/
|
|
209
|
-
const measureComponent = useCallback(
|
|
210
|
-
(
|
|
211
|
-
comp: React.ElementType,
|
|
212
|
-
props: { onLoadFinished: () => void; [key: string]: any }
|
|
213
|
-
): Promise<MeasurementResult> => {
|
|
214
|
-
return new Promise((resolve) => {
|
|
215
|
-
log_debug("Measuring process started", { comp, props });
|
|
216
|
-
|
|
217
|
-
dispatch({
|
|
218
|
-
type: MEASUREMENT_ACTIONS.setMeasureCallback,
|
|
219
|
-
payload: resolve,
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
dispatch({
|
|
223
|
-
type: MEASUREMENT_ACTIONS.setMeasuringProgress,
|
|
224
|
-
payload: true,
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
dispatch({
|
|
228
|
-
type: MEASUREMENT_ACTIONS.setOnLoadFinished,
|
|
229
|
-
payload: false,
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
dispatch({
|
|
233
|
-
type: MEASUREMENT_ACTIONS.setLayout,
|
|
234
|
-
payload: { width: 0, height: 0 },
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
onLoadFinishedRef.current =
|
|
238
|
-
// eslint-disable-next-line react/prop-types
|
|
239
|
-
props.onLoadFinished as MeasurementsPortalProps["onLoadFinished"];
|
|
240
|
-
|
|
241
|
-
const handleOnLoadFinish = (...args: any[]) => {
|
|
242
|
-
if (args?.[0]?.error && isError(args[0].error)) {
|
|
243
|
-
log_debug(
|
|
244
|
-
"Component called onLoadFinish with an error, completing measurement process",
|
|
245
|
-
{ args }
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
finalize();
|
|
249
|
-
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
log_debug(
|
|
254
|
-
"Component called onLoadFinish, completing measurement process",
|
|
255
|
-
{ args }
|
|
256
|
-
);
|
|
63
|
+
setMeasureComponentCallback(null);
|
|
64
|
+
setMeasuringInProgress(false);
|
|
65
|
+
onLoadFinishedIsCalled.current = false;
|
|
66
|
+
};
|
|
257
67
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
68
|
+
const setComponentProps = (props) => {
|
|
69
|
+
const handleOnLoadFinish = (...args) => {
|
|
70
|
+
const error = R.path([0, "error"], args);
|
|
71
|
+
|
|
72
|
+
if (isError(error)) {
|
|
73
|
+
finalize({ width: 0, height: 0 });
|
|
74
|
+
} else {
|
|
75
|
+
onLoadFinishedIsCalled.current = true;
|
|
76
|
+
props.onLoadFinished(...args);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
componentProps.current = {
|
|
81
|
+
...props,
|
|
82
|
+
onLoadFinished: handleOnLoadFinish,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
262
85
|
|
|
263
|
-
|
|
264
|
-
|
|
86
|
+
const measureComponent = React.useCallback(async (comp, props) => {
|
|
87
|
+
return new Promise((resolve) => {
|
|
88
|
+
setMeasureComponentCallback(resolve);
|
|
89
|
+
setMeasuringInProgress(true);
|
|
265
90
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
91
|
+
setComponentProps(props);
|
|
92
|
+
setComponent(comp);
|
|
93
|
+
});
|
|
94
|
+
}, []);
|
|
270
95
|
|
|
271
|
-
|
|
272
|
-
|
|
96
|
+
const onLayout = ({
|
|
97
|
+
nativeEvent: {
|
|
98
|
+
layout: { width, height },
|
|
273
99
|
},
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
[measureComponent, state.measuringInProgress]
|
|
283
|
-
);
|
|
100
|
+
}) => {
|
|
101
|
+
if (measureComponentCallback.current && onLoadFinishedIsCalled.current) {
|
|
102
|
+
finalize({
|
|
103
|
+
width,
|
|
104
|
+
height,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
};
|
|
284
108
|
|
|
285
109
|
return (
|
|
286
110
|
<>
|
|
287
111
|
<MeasurementsPortal
|
|
288
|
-
Component={
|
|
289
|
-
componentProps={
|
|
290
|
-
onLayout={onLayout
|
|
112
|
+
Component={Component.current}
|
|
113
|
+
componentProps={componentProps.current}
|
|
114
|
+
onLayout={onLayout}
|
|
291
115
|
/>
|
|
292
|
-
<MeasurementPortalContext.Provider
|
|
116
|
+
<MeasurementPortalContext.Provider
|
|
117
|
+
value={{
|
|
118
|
+
measureComponent,
|
|
119
|
+
measuringInProgress,
|
|
120
|
+
}}
|
|
121
|
+
>
|
|
293
122
|
{children}
|
|
294
123
|
</MeasurementPortalContext.Provider>
|
|
295
124
|
</>
|
|
@@ -37,6 +37,11 @@ type Props = {
|
|
|
37
37
|
const defaultStyles = StyleSheet.create({
|
|
38
38
|
playerContainer: { position: "relative", alignSelf: "center", zIndex: 200 },
|
|
39
39
|
playerDetails: { flex: 1, paddingTop: 20 },
|
|
40
|
+
inlinePlayerContainerDimensions: {
|
|
41
|
+
aspectRatio: 16 / 9,
|
|
42
|
+
width: "100%",
|
|
43
|
+
height: undefined,
|
|
44
|
+
},
|
|
40
45
|
});
|
|
41
46
|
|
|
42
47
|
const orientationStyles = StyleSheet.create({
|
|
@@ -190,12 +195,9 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
190
195
|
defaultStyles.playerContainer,
|
|
191
196
|
containerDimensions,
|
|
192
197
|
containerStyle,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
? containerDimensions.height + 10
|
|
197
|
-
: containerDimensions.height,
|
|
198
|
-
},
|
|
198
|
+
isInlineModal && !docked && !isTabletLandscape
|
|
199
|
+
? defaultStyles.inlinePlayerContainerDimensions
|
|
200
|
+
: {},
|
|
199
201
|
playerDimesionsHack,
|
|
200
202
|
]}
|
|
201
203
|
>
|
|
@@ -40,7 +40,9 @@ exports[`PlayerWrapper renders inline 1`] = `
|
|
|
40
40
|
},
|
|
41
41
|
Object {},
|
|
42
42
|
Object {
|
|
43
|
-
"
|
|
43
|
+
"aspectRatio": 1.7777777777777777,
|
|
44
|
+
"height": undefined,
|
|
45
|
+
"width": "100%",
|
|
44
46
|
},
|
|
45
47
|
Object {},
|
|
46
48
|
]
|
|
@@ -109,9 +111,7 @@ exports[`PlayerWrapper renders inline and docked 1`] = `
|
|
|
109
111
|
"width": 300,
|
|
110
112
|
},
|
|
111
113
|
Object {},
|
|
112
|
-
Object {
|
|
113
|
-
"height": 50,
|
|
114
|
-
},
|
|
114
|
+
Object {},
|
|
115
115
|
Object {},
|
|
116
116
|
]
|
|
117
117
|
}
|
|
@@ -167,9 +167,7 @@ exports[`PlayerWrapper renders inline on tablet in landscape orientation 1`] = `
|
|
|
167
167
|
"width": 195,
|
|
168
168
|
},
|
|
169
169
|
Object {},
|
|
170
|
-
Object {
|
|
171
|
-
"height": 119.6875,
|
|
172
|
-
},
|
|
170
|
+
Object {},
|
|
173
171
|
Object {},
|
|
174
172
|
]
|
|
175
173
|
}
|
|
@@ -237,9 +235,7 @@ exports[`PlayerWrapper renders properly 1`] = `
|
|
|
237
235
|
"width": 300,
|
|
238
236
|
},
|
|
239
237
|
Object {},
|
|
240
|
-
Object {
|
|
241
|
-
"height": 800,
|
|
242
|
-
},
|
|
238
|
+
Object {},
|
|
243
239
|
Object {},
|
|
244
240
|
]
|
|
245
241
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.5882013252",
|
|
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",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"redux-mock-store": "^1.5.3"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@applicaster/applicaster-types": "12.0.0-alpha.
|
|
39
|
-
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.
|
|
40
|
-
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.
|
|
41
|
-
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.
|
|
38
|
+
"@applicaster/applicaster-types": "12.0.0-alpha.5882013252",
|
|
39
|
+
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.5882013252",
|
|
40
|
+
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.5882013252",
|
|
41
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.5882013252",
|
|
42
42
|
"promise": "^8.3.0",
|
|
43
43
|
"react-router-native": "^5.1.2",
|
|
44
44
|
"url": "^0.11.0",
|