@applicaster/zapp-react-native-ui-components
Version:
Applicaster Zapp React Native ui components for the Quick Brick App
82 lines (69 loc) • 2.05 kB
text/typescript
import * as React from "react";
import { View, findNodeHandle } from "react-native";
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
import { MasterCellAsyncRenderManager } from "./MasterCellAsyncRenderManager";
const layoutMeasure = (viewRef, onMeasure) => {
viewRef?.measureLayout?.(
findNodeHandle(viewRef),
(x, y, width, height) => {
onMeasure({ width, height });
},
noop
);
};
const regularMeasure = (viewRef, onMeasure) => {
viewRef?.measure?.((x, y, width, height) => {
onMeasure({ width, height });
});
};
const measure = platformSelect({
android: layoutMeasure,
android_tv: layoutMeasure,
default: regularMeasure,
});
type Dimensions = {
width: Option<number>;
height: Option<number>;
};
type Return = {
emitAsyncElementRegistrate: () => void;
emitAsyncElementLayout: () => void;
onCellLayout: () => void;
dimensions: Dimensions;
resetDimensions: () => void;
};
const initialDimensions = () => ({
width: undefined,
height: undefined,
});
export const useAsyncRendering = (viewRef: React.RefObject<View>): Return => {
const [dimensions, setDimensions] = React.useState(initialDimensions());
const managerRef = React.useRef(
new MasterCellAsyncRenderManager(() => {
measure(viewRef?.current, ({ width, height }) => {
setDimensions({
width,
height: Math.ceil(height),
});
});
})
);
React.useEffect(() => {
return managerRef.current.start();
}, []);
const resetDimensions = React.useCallback(() => {
setDimensions(initialDimensions());
}, []);
return React.useMemo(
() => ({
emitAsyncElementRegistrate:
managerRef.current?.emitAsyncElementRegistrate,
emitAsyncElementLayout: managerRef.current.emitAsyncElementLayout,
dimensions,
onCellLayout: managerRef.current.onCellLayout,
resetDimensions,
}),
[dimensions, resetDimensions]
);
};