@xhsreds/reds-rn-next 0.8.4-image-optimization202510221852 → 0.8.4-image-optimization202510222117

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.
Files changed (45) hide show
  1. package/coverage/.tmp/coverage-1.json +1 -1
  2. package/coverage/.tmp/coverage-10.json +1 -1
  3. package/coverage/.tmp/coverage-11.json +1 -1
  4. package/coverage/.tmp/coverage-12.json +1 -1
  5. package/coverage/.tmp/coverage-13.json +1 -1
  6. package/coverage/.tmp/coverage-14.json +1 -1
  7. package/coverage/.tmp/coverage-15.json +1 -1
  8. package/coverage/.tmp/coverage-16.json +1 -1
  9. package/coverage/.tmp/coverage-17.json +1 -1
  10. package/coverage/.tmp/coverage-18.json +1 -1
  11. package/coverage/.tmp/coverage-19.json +1 -1
  12. package/coverage/.tmp/coverage-2.json +1 -1
  13. package/coverage/.tmp/coverage-20.json +1 -1
  14. package/coverage/.tmp/coverage-21.json +1 -1
  15. package/coverage/.tmp/coverage-22.json +1 -1
  16. package/coverage/.tmp/coverage-23.json +1 -1
  17. package/coverage/.tmp/coverage-24.json +1 -1
  18. package/coverage/.tmp/coverage-25.json +1 -1
  19. package/coverage/.tmp/coverage-26.json +1 -1
  20. package/coverage/.tmp/coverage-27.json +1 -1
  21. package/coverage/.tmp/coverage-28.json +1 -1
  22. package/coverage/.tmp/coverage-29.json +1 -1
  23. package/coverage/.tmp/coverage-3.json +1 -1
  24. package/coverage/.tmp/coverage-30.json +1 -1
  25. package/coverage/.tmp/coverage-31.json +1 -1
  26. package/coverage/.tmp/coverage-32.json +1 -1
  27. package/coverage/.tmp/coverage-33.json +1 -1
  28. package/coverage/.tmp/coverage-35.json +1 -1
  29. package/coverage/.tmp/coverage-36.json +1 -1
  30. package/coverage/.tmp/coverage-37.json +1 -1
  31. package/coverage/.tmp/coverage-38.json +1 -1
  32. package/coverage/.tmp/coverage-4.json +1 -1
  33. package/coverage/.tmp/coverage-5.json +1 -1
  34. package/coverage/.tmp/coverage-6.json +1 -1
  35. package/coverage/.tmp/coverage-7.json +1 -1
  36. package/coverage/.tmp/coverage-8.json +1 -1
  37. package/coverage/.tmp/coverage-9.json +1 -1
  38. package/lib/cjs/components/Image/VisibilitySensor.js +20 -73
  39. package/lib/cjs/components/Image/VisibilitySensor.js.map +1 -1
  40. package/lib/esm/components/Image/VisibilitySensor.js +22 -75
  41. package/lib/esm/components/Image/VisibilitySensor.js.map +1 -1
  42. package/package.json +1 -1
  43. package/src/components/Image/VisibilitySensor.tsx +35 -81
  44. package/src/i18n/@types/resources.d.ts +18 -18
  45. package/src/i18n/index.json +31 -31
@@ -1 +1 @@
1
- {"version":3,"file":"VisibilitySensor.js","sources":["../../../../src/components/Image/VisibilitySensor.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState, forwardRef, useImperativeHandle } from \"react\";\nimport { Dimensions, type ScaledSize, View } from \"react-native\";\nimport type { VisibilitySensorRef, VisibilitySensorProps, RectDimensionsState } from \"./interface/visibilitySensor\";\n// function useInterval(callback: () => void, delay: number | null) {\n// const savedCallback = useRef(callback);\n// useEffect(() => {\n// savedCallback.current = callback;\n// }, [callback]);\n// useEffect(() => {\n// if (delay === null || delay === undefined) {\n// return;\n// }\n// const id = setInterval(() => savedCallback.current(), delay);\n// return () => clearInterval(id);\n// }, [delay]);\n// }\nconst VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>((props, ref) => {\n const { onChange, disabled = false, triggerOnce = false, delay, threshold = {}, children, ...rest } = props;\n const localRef = useRef<View>(null);\n const hasMountedRef = useRef(false);\n useImperativeHandle(ref, () => ({\n getInnerRef: () => localRef.current,\n }));\n const [rectDimensions, setRectDimensions] = useState<RectDimensionsState>({\n rectTop: 0,\n rectBottom: 0,\n rectLeft: 0,\n rectRight: 0,\n rectWidth: 0,\n rectHeight: 0,\n });\n const [lastValue, setLastValue] = useState<boolean | undefined>(undefined);\n const [active, setActive] = useState<boolean>(false);\n const measureInnerView = () => {\n if (!active) return;\n localRef.current?.measure((_x: number, _y: number, width: number, height: number, pageX: number, pageY: number) => {\n const dimensions = {\n rectTop: pageY,\n rectBottom: pageY + height,\n rectLeft: pageX,\n rectRight: pageX + width,\n rectWidth: width,\n rectHeight: height,\n };\n if (\n rectDimensions.rectTop !== dimensions.rectTop ||\n rectDimensions.rectBottom !== dimensions.rectBottom ||\n rectDimensions.rectLeft !== dimensions.rectLeft ||\n rectDimensions.rectRight !== dimensions.rectRight ||\n rectDimensions.rectWidth !== dimensions.rectWidth ||\n rectDimensions.rectHeight !== dimensions.rectHeight\n ) {\n setRectDimensions(dimensions);\n }\n });\n };\n // useInterval(measureInnerView, delay || 100);\n const startWatching = useCallback(() => {\n if (!active) setActive(true);\n }, [active]);\n const stopWatching = useCallback(() => {\n if (active) setActive(false);\n }, [active]);\n useEffect(() => {\n if (!disabled) {\n startWatching();\n }\n return () => {\n stopWatching();\n };\n }, [disabled, startWatching, stopWatching]);\n useEffect(() => {\n if (!hasMountedRef.current) {\n hasMountedRef.current = true;\n return;\n }\n const window: ScaledSize = Dimensions.get(\"window\");\n const isVisible: boolean =\n rectDimensions.rectTop + (threshold.top || 0) <= window.height && // Top edge is within the bottom of the window\n rectDimensions.rectBottom - (threshold.bottom || 0) >= 0 && // Bottom edge is within the top of the window\n rectDimensions.rectLeft + (threshold.left || 0) <= window.width && // Left edge is within the right of the window\n rectDimensions.rectRight - (threshold.right || 0) >= 0; // Right edge is within the left of the window\n if (lastValue !== isVisible) {\n setLastValue(isVisible);\n onChange(isVisible);\n if (isVisible && triggerOnce) {\n stopWatching();\n }\n }\n }, [rectDimensions, lastValue, threshold, onChange, triggerOnce, stopWatching]);\n return (\n <View ref={localRef} {...rest} onLayout={() => measureInnerView()}>\n {children}\n </View>\n );\n});\nexport default VisibilitySensor;\n"],"names":["VisibilitySensor","forwardRef","props","ref","onChange","_props$disabled","disabled","_props$triggerOnce","triggerOnce","delay","_props$threshold","threshold","children","rest","_excluded","localRef","useRef","hasMountedRef","useImperativeHandle","getInnerRef","current","_useState","useState","rectTop","rectBottom","rectLeft","rectRight","rectWidth","rectHeight","_useState2","_slicedToArray","rectDimensions","setRectDimensions","_useState3","_useState4","lastValue","setLastValue","_useState5","_useState6","active","setActive","measureInnerView","_localRef$current","measure","_x","_y","width","height","pageX","pageY","dimensions","startWatching","useCallback","stopWatching","useEffect","window","Dimensions","get","isVisible","top","bottom","left","right","React","createElement","View","_objectSpread","onLayout"],"mappings":"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"}
1
+ {"version":3,"file":"VisibilitySensor.js","sources":["../../../../src/components/Image/VisibilitySensor.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, forwardRef, useImperativeHandle } from \"react\";\nimport { Dimensions, View } from \"react-native\";\nimport type { VisibilitySensorRef, VisibilitySensorProps } from \"./interface/visibilitySensor\";\n\nconst VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>((props, ref) => {\n const { onChange, disabled = false, triggerOnce = false, delay, threshold = {}, children, ...rest } = props;\n const localRef = useRef<View>(null);\n const lastVisibleRef = useRef<boolean | undefined>(undefined);\n const measuredOnceRef = useRef<boolean>(false);\n\n useImperativeHandle(ref, () => ({\n getInnerRef: () => localRef.current,\n }));\n\n // Compute visibility once using native measure; avoid react state to prevent layout loops\n const measureAndNotify = useCallback(() => {\n if (disabled || measuredOnceRef.current) return;\n const win = Dimensions.get(\"window\");\n localRef.current?.measure((_, __, width: number, height: number, pageX: number, pageY: number) => {\n const isVisible =\n pageY + (threshold.top || 0) <= win.height &&\n pageY + height - (threshold.bottom || 0) >= 0 &&\n pageX + (threshold.left || 0) <= win.width &&\n pageX + width - (threshold.right || 0) >= 0;\n\n if (lastVisibleRef.current !== isVisible) {\n lastVisibleRef.current = isVisible;\n onChange(isVisible);\n // Only measure once to match original behavior\n measuredOnceRef.current = true;\n }\n });\n }, [disabled, onChange, threshold]);\n\n // Keep active in sync with disabled prop\n useEffect(() => {\n // If it becomes enabled and we haven't measured yet, measure once now\n if (!disabled && !measuredOnceRef.current) {\n // Defer to allow layout to settle\n requestAnimationFrame(() => measureAndNotify());\n }\n }, [disabled, measureAndNotify]);\n\n return (\n <View ref={localRef} {...rest} onLayout={measureAndNotify}>\n {children}\n </View>\n );\n});\n\nexport default VisibilitySensor;\n"],"names":["VisibilitySensor","forwardRef","props","ref","onChange","_props$disabled","disabled","triggerOnce","delay","_props$threshold","threshold","children","rest","_excluded","localRef","useRef","lastVisibleRef","measuredOnceRef","useImperativeHandle","getInnerRef","current","measureAndNotify","useCallback","_localRef$current","win","Dimensions","get","measure","_","__","width","height","pageX","pageY","isVisible","top","bottom","left","right","useEffect","requestAnimationFrame","React","createElement","View","onLayout"],"mappings":"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"}
@@ -1,21 +1,21 @@
1
- import { i as _objectWithoutProperties, _ as _slicedToArray, a as _objectSpread2 } from '../../_chunks/DpFbw-p-.js';
2
- import React, { forwardRef, useRef, useImperativeHandle, useState, useCallback, useEffect } from 'react';
1
+ import { i as _objectWithoutProperties, a as _objectSpread2 } from '../../_chunks/DpFbw-p-.js';
2
+ import React, { forwardRef, useRef, useImperativeHandle, useCallback, useEffect } from 'react';
3
3
  import { Dimensions, View } from 'react-native';
4
4
 
5
5
  var _excluded = ["onChange", "disabled", "triggerOnce", "delay", "threshold", "children"];
6
6
  var VisibilitySensor = /*#__PURE__*/forwardRef(function (props, ref) {
7
7
  var onChange = props.onChange,
8
8
  _props$disabled = props.disabled,
9
- disabled = _props$disabled === void 0 ? false : _props$disabled,
10
- _props$triggerOnce = props.triggerOnce,
11
- triggerOnce = _props$triggerOnce === void 0 ? false : _props$triggerOnce;
9
+ disabled = _props$disabled === void 0 ? false : _props$disabled;
10
+ props.triggerOnce;
12
11
  props.delay;
13
12
  var _props$threshold = props.threshold,
14
13
  threshold = _props$threshold === void 0 ? {} : _props$threshold,
15
14
  children = props.children,
16
15
  rest = _objectWithoutProperties(props, _excluded);
17
16
  var localRef = useRef(null);
18
- var hasMountedRef = useRef(false);
17
+ var lastVisibleRef = useRef(void 0);
18
+ var measuredOnceRef = useRef(false);
19
19
  useImperativeHandle(ref, function () {
20
20
  return {
21
21
  getInnerRef: function getInnerRef() {
@@ -23,83 +23,30 @@ var VisibilitySensor = /*#__PURE__*/forwardRef(function (props, ref) {
23
23
  }
24
24
  };
25
25
  });
26
- var _useState = useState({
27
- rectTop: 0,
28
- rectBottom: 0,
29
- rectLeft: 0,
30
- rectRight: 0,
31
- rectWidth: 0,
32
- rectHeight: 0
33
- }),
34
- _useState2 = _slicedToArray(_useState, 2),
35
- rectDimensions = _useState2[0],
36
- setRectDimensions = _useState2[1];
37
- var _useState3 = useState(void 0),
38
- _useState4 = _slicedToArray(_useState3, 2),
39
- lastValue = _useState4[0],
40
- setLastValue = _useState4[1];
41
- var _useState5 = useState(false),
42
- _useState6 = _slicedToArray(_useState5, 2),
43
- active = _useState6[0],
44
- setActive = _useState6[1];
45
- var measureInnerView = function measureInnerView() {
26
+ var measureAndNotify = useCallback(function () {
46
27
  var _localRef$current;
47
- if (!active) return;
48
- (_localRef$current = localRef.current) === null || _localRef$current === void 0 || _localRef$current.measure(function (_x, _y, width, height, pageX, pageY) {
49
- var dimensions = {
50
- rectTop: pageY,
51
- rectBottom: pageY + height,
52
- rectLeft: pageX,
53
- rectRight: pageX + width,
54
- rectWidth: width,
55
- rectHeight: height
56
- };
57
- if (rectDimensions.rectTop !== dimensions.rectTop || rectDimensions.rectBottom !== dimensions.rectBottom || rectDimensions.rectLeft !== dimensions.rectLeft || rectDimensions.rectRight !== dimensions.rectRight || rectDimensions.rectWidth !== dimensions.rectWidth || rectDimensions.rectHeight !== dimensions.rectHeight) {
58
- setRectDimensions(dimensions);
28
+ if (disabled || measuredOnceRef.current) return;
29
+ var win = Dimensions.get("window");
30
+ (_localRef$current = localRef.current) === null || _localRef$current === void 0 || _localRef$current.measure(function (_, __, width, height, pageX, pageY) {
31
+ var isVisible = pageY + (threshold.top || 0) <= win.height && pageY + height - (threshold.bottom || 0) >= 0 && pageX + (threshold.left || 0) <= win.width && pageX + width - (threshold.right || 0) >= 0;
32
+ if (lastVisibleRef.current !== isVisible) {
33
+ lastVisibleRef.current = isVisible;
34
+ onChange(isVisible);
35
+ measuredOnceRef.current = true;
59
36
  }
60
37
  });
61
- };
62
- var startWatching = useCallback(function () {
63
- if (!active) setActive(true);
64
- }, [active]);
65
- var stopWatching = useCallback(function () {
66
- if (active) setActive(false);
67
- }, [active]);
38
+ }, [disabled, onChange, threshold]);
68
39
  useEffect(function () {
69
- if (!disabled) {
70
- startWatching();
40
+ if (!disabled && !measuredOnceRef.current) {
41
+ requestAnimationFrame(function () {
42
+ return measureAndNotify();
43
+ });
71
44
  }
72
- return function () {
73
- stopWatching();
74
- };
75
- }, [disabled, startWatching, stopWatching]);
76
- useEffect(function () {
77
- if (!hasMountedRef.current) {
78
- hasMountedRef.current = true;
79
- return;
80
- }
81
- var window = Dimensions.get("window");
82
- var isVisible = rectDimensions.rectTop + (threshold.top || 0) <= window.height &&
83
- // Top edge is within the bottom of the window
84
- rectDimensions.rectBottom - (threshold.bottom || 0) >= 0 &&
85
- // Bottom edge is within the top of the window
86
- rectDimensions.rectLeft + (threshold.left || 0) <= window.width &&
87
- // Left edge is within the right of the window
88
- rectDimensions.rectRight - (threshold.right || 0) >= 0;
89
- if (lastValue !== isVisible) {
90
- setLastValue(isVisible);
91
- onChange(isVisible);
92
- if (isVisible && triggerOnce) {
93
- stopWatching();
94
- }
95
- }
96
- }, [rectDimensions, lastValue, threshold, onChange, triggerOnce, stopWatching]);
45
+ }, [disabled, measureAndNotify]);
97
46
  return /* @__PURE__ */React.createElement(View, _objectSpread2(_objectSpread2({
98
47
  ref: localRef
99
48
  }, rest), {}, {
100
- onLayout: function onLayout() {
101
- return measureInnerView();
102
- }
49
+ onLayout: measureAndNotify
103
50
  }), children);
104
51
  });
105
52
 
@@ -1 +1 @@
1
- {"version":3,"file":"VisibilitySensor.js","sources":["../../../../src/components/Image/VisibilitySensor.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState, forwardRef, useImperativeHandle } from \"react\";\nimport { Dimensions, type ScaledSize, View } from \"react-native\";\nimport type { VisibilitySensorRef, VisibilitySensorProps, RectDimensionsState } from \"./interface/visibilitySensor\";\n// function useInterval(callback: () => void, delay: number | null) {\n// const savedCallback = useRef(callback);\n// useEffect(() => {\n// savedCallback.current = callback;\n// }, [callback]);\n// useEffect(() => {\n// if (delay === null || delay === undefined) {\n// return;\n// }\n// const id = setInterval(() => savedCallback.current(), delay);\n// return () => clearInterval(id);\n// }, [delay]);\n// }\nconst VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>((props, ref) => {\n const { onChange, disabled = false, triggerOnce = false, delay, threshold = {}, children, ...rest } = props;\n const localRef = useRef<View>(null);\n const hasMountedRef = useRef(false);\n useImperativeHandle(ref, () => ({\n getInnerRef: () => localRef.current,\n }));\n const [rectDimensions, setRectDimensions] = useState<RectDimensionsState>({\n rectTop: 0,\n rectBottom: 0,\n rectLeft: 0,\n rectRight: 0,\n rectWidth: 0,\n rectHeight: 0,\n });\n const [lastValue, setLastValue] = useState<boolean | undefined>(undefined);\n const [active, setActive] = useState<boolean>(false);\n const measureInnerView = () => {\n if (!active) return;\n localRef.current?.measure((_x: number, _y: number, width: number, height: number, pageX: number, pageY: number) => {\n const dimensions = {\n rectTop: pageY,\n rectBottom: pageY + height,\n rectLeft: pageX,\n rectRight: pageX + width,\n rectWidth: width,\n rectHeight: height,\n };\n if (\n rectDimensions.rectTop !== dimensions.rectTop ||\n rectDimensions.rectBottom !== dimensions.rectBottom ||\n rectDimensions.rectLeft !== dimensions.rectLeft ||\n rectDimensions.rectRight !== dimensions.rectRight ||\n rectDimensions.rectWidth !== dimensions.rectWidth ||\n rectDimensions.rectHeight !== dimensions.rectHeight\n ) {\n setRectDimensions(dimensions);\n }\n });\n };\n // useInterval(measureInnerView, delay || 100);\n const startWatching = useCallback(() => {\n if (!active) setActive(true);\n }, [active]);\n const stopWatching = useCallback(() => {\n if (active) setActive(false);\n }, [active]);\n useEffect(() => {\n if (!disabled) {\n startWatching();\n }\n return () => {\n stopWatching();\n };\n }, [disabled, startWatching, stopWatching]);\n useEffect(() => {\n if (!hasMountedRef.current) {\n hasMountedRef.current = true;\n return;\n }\n const window: ScaledSize = Dimensions.get(\"window\");\n const isVisible: boolean =\n rectDimensions.rectTop + (threshold.top || 0) <= window.height && // Top edge is within the bottom of the window\n rectDimensions.rectBottom - (threshold.bottom || 0) >= 0 && // Bottom edge is within the top of the window\n rectDimensions.rectLeft + (threshold.left || 0) <= window.width && // Left edge is within the right of the window\n rectDimensions.rectRight - (threshold.right || 0) >= 0; // Right edge is within the left of the window\n if (lastValue !== isVisible) {\n setLastValue(isVisible);\n onChange(isVisible);\n if (isVisible && triggerOnce) {\n stopWatching();\n }\n }\n }, [rectDimensions, lastValue, threshold, onChange, triggerOnce, stopWatching]);\n return (\n <View ref={localRef} {...rest} onLayout={() => measureInnerView()}>\n {children}\n </View>\n );\n});\nexport default VisibilitySensor;\n"],"names":["VisibilitySensor","forwardRef","props","ref","onChange","_props$disabled","disabled","_props$triggerOnce","triggerOnce","delay","_props$threshold","threshold","children","rest","_excluded","localRef","useRef","hasMountedRef","useImperativeHandle","getInnerRef","current","_useState","useState","rectTop","rectBottom","rectLeft","rectRight","rectWidth","rectHeight","_useState2","_slicedToArray","rectDimensions","setRectDimensions","_useState3","_useState4","lastValue","setLastValue","_useState5","_useState6","active","setActive","measureInnerView","_localRef$current","measure","_x","_y","width","height","pageX","pageY","dimensions","startWatching","useCallback","stopWatching","useEffect","window","Dimensions","get","isVisible","top","bottom","left","right","React","createElement","View","_objectSpread","onLayout"],"mappings":"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"}
1
+ {"version":3,"file":"VisibilitySensor.js","sources":["../../../../src/components/Image/VisibilitySensor.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, forwardRef, useImperativeHandle } from \"react\";\nimport { Dimensions, View } from \"react-native\";\nimport type { VisibilitySensorRef, VisibilitySensorProps } from \"./interface/visibilitySensor\";\n\nconst VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>((props, ref) => {\n const { onChange, disabled = false, triggerOnce = false, delay, threshold = {}, children, ...rest } = props;\n const localRef = useRef<View>(null);\n const lastVisibleRef = useRef<boolean | undefined>(undefined);\n const measuredOnceRef = useRef<boolean>(false);\n\n useImperativeHandle(ref, () => ({\n getInnerRef: () => localRef.current,\n }));\n\n // Compute visibility once using native measure; avoid react state to prevent layout loops\n const measureAndNotify = useCallback(() => {\n if (disabled || measuredOnceRef.current) return;\n const win = Dimensions.get(\"window\");\n localRef.current?.measure((_, __, width: number, height: number, pageX: number, pageY: number) => {\n const isVisible =\n pageY + (threshold.top || 0) <= win.height &&\n pageY + height - (threshold.bottom || 0) >= 0 &&\n pageX + (threshold.left || 0) <= win.width &&\n pageX + width - (threshold.right || 0) >= 0;\n\n if (lastVisibleRef.current !== isVisible) {\n lastVisibleRef.current = isVisible;\n onChange(isVisible);\n // Only measure once to match original behavior\n measuredOnceRef.current = true;\n }\n });\n }, [disabled, onChange, threshold]);\n\n // Keep active in sync with disabled prop\n useEffect(() => {\n // If it becomes enabled and we haven't measured yet, measure once now\n if (!disabled && !measuredOnceRef.current) {\n // Defer to allow layout to settle\n requestAnimationFrame(() => measureAndNotify());\n }\n }, [disabled, measureAndNotify]);\n\n return (\n <View ref={localRef} {...rest} onLayout={measureAndNotify}>\n {children}\n </View>\n );\n});\n\nexport default VisibilitySensor;\n"],"names":["VisibilitySensor","forwardRef","props","ref","onChange","_props$disabled","disabled","triggerOnce","delay","_props$threshold","threshold","children","rest","_excluded","localRef","useRef","lastVisibleRef","measuredOnceRef","useImperativeHandle","getInnerRef","current","measureAndNotify","useCallback","_localRef$current","win","Dimensions","get","measure","_","__","width","height","pageX","pageY","isVisible","top","bottom","left","right","useEffect","requestAnimationFrame","React","createElement","View","onLayout"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xhsreds/reds-rn-next",
3
- "version": "0.8.4-image-optimization202510221852",
3
+ "version": "0.8.4-image-optimization202510222117",
4
4
  "author": "贾斌(呀哈) <jiabin@xiaohongshu.com>",
5
5
  "license": "ISC",
6
6
  "dependencies": {
@@ -1,97 +1,51 @@
1
- import React, { useCallback, useEffect, useRef, useState, forwardRef, useImperativeHandle } from "react";
2
- import { Dimensions, type ScaledSize, View } from "react-native";
3
- import type { VisibilitySensorRef, VisibilitySensorProps, RectDimensionsState } from "./interface/visibilitySensor";
4
- // function useInterval(callback: () => void, delay: number | null) {
5
- // const savedCallback = useRef(callback);
6
- // useEffect(() => {
7
- // savedCallback.current = callback;
8
- // }, [callback]);
9
- // useEffect(() => {
10
- // if (delay === null || delay === undefined) {
11
- // return;
12
- // }
13
- // const id = setInterval(() => savedCallback.current(), delay);
14
- // return () => clearInterval(id);
15
- // }, [delay]);
16
- // }
1
+ import React, { useCallback, useEffect, useRef, forwardRef, useImperativeHandle } from "react";
2
+ import { Dimensions, View } from "react-native";
3
+ import type { VisibilitySensorRef, VisibilitySensorProps } from "./interface/visibilitySensor";
4
+
17
5
  const VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>((props, ref) => {
18
6
  const { onChange, disabled = false, triggerOnce = false, delay, threshold = {}, children, ...rest } = props;
19
7
  const localRef = useRef<View>(null);
20
- const hasMountedRef = useRef(false);
8
+ const lastVisibleRef = useRef<boolean | undefined>(undefined);
9
+ const measuredOnceRef = useRef<boolean>(false);
10
+
21
11
  useImperativeHandle(ref, () => ({
22
12
  getInnerRef: () => localRef.current,
23
13
  }));
24
- const [rectDimensions, setRectDimensions] = useState<RectDimensionsState>({
25
- rectTop: 0,
26
- rectBottom: 0,
27
- rectLeft: 0,
28
- rectRight: 0,
29
- rectWidth: 0,
30
- rectHeight: 0,
31
- });
32
- const [lastValue, setLastValue] = useState<boolean | undefined>(undefined);
33
- const [active, setActive] = useState<boolean>(false);
34
- const measureInnerView = () => {
35
- if (!active) return;
36
- localRef.current?.measure((_x: number, _y: number, width: number, height: number, pageX: number, pageY: number) => {
37
- const dimensions = {
38
- rectTop: pageY,
39
- rectBottom: pageY + height,
40
- rectLeft: pageX,
41
- rectRight: pageX + width,
42
- rectWidth: width,
43
- rectHeight: height,
44
- };
45
- if (
46
- rectDimensions.rectTop !== dimensions.rectTop ||
47
- rectDimensions.rectBottom !== dimensions.rectBottom ||
48
- rectDimensions.rectLeft !== dimensions.rectLeft ||
49
- rectDimensions.rectRight !== dimensions.rectRight ||
50
- rectDimensions.rectWidth !== dimensions.rectWidth ||
51
- rectDimensions.rectHeight !== dimensions.rectHeight
52
- ) {
53
- setRectDimensions(dimensions);
14
+
15
+ // Compute visibility once using native measure; avoid react state to prevent layout loops
16
+ const measureAndNotify = useCallback(() => {
17
+ if (disabled || measuredOnceRef.current) return;
18
+ const win = Dimensions.get("window");
19
+ localRef.current?.measure((_, __, width: number, height: number, pageX: number, pageY: number) => {
20
+ const isVisible =
21
+ pageY + (threshold.top || 0) <= win.height &&
22
+ pageY + height - (threshold.bottom || 0) >= 0 &&
23
+ pageX + (threshold.left || 0) <= win.width &&
24
+ pageX + width - (threshold.right || 0) >= 0;
25
+
26
+ if (lastVisibleRef.current !== isVisible) {
27
+ lastVisibleRef.current = isVisible;
28
+ onChange(isVisible);
29
+ // Only measure once to match original behavior
30
+ measuredOnceRef.current = true;
54
31
  }
55
32
  });
56
- };
57
- // useInterval(measureInnerView, delay || 100);
58
- const startWatching = useCallback(() => {
59
- if (!active) setActive(true);
60
- }, [active]);
61
- const stopWatching = useCallback(() => {
62
- if (active) setActive(false);
63
- }, [active]);
33
+ }, [disabled, onChange, threshold]);
34
+
35
+ // Keep active in sync with disabled prop
64
36
  useEffect(() => {
65
- if (!disabled) {
66
- startWatching();
37
+ // If it becomes enabled and we haven't measured yet, measure once now
38
+ if (!disabled && !measuredOnceRef.current) {
39
+ // Defer to allow layout to settle
40
+ requestAnimationFrame(() => measureAndNotify());
67
41
  }
68
- return () => {
69
- stopWatching();
70
- };
71
- }, [disabled, startWatching, stopWatching]);
72
- useEffect(() => {
73
- if (!hasMountedRef.current) {
74
- hasMountedRef.current = true;
75
- return;
76
- }
77
- const window: ScaledSize = Dimensions.get("window");
78
- const isVisible: boolean =
79
- rectDimensions.rectTop + (threshold.top || 0) <= window.height && // Top edge is within the bottom of the window
80
- rectDimensions.rectBottom - (threshold.bottom || 0) >= 0 && // Bottom edge is within the top of the window
81
- rectDimensions.rectLeft + (threshold.left || 0) <= window.width && // Left edge is within the right of the window
82
- rectDimensions.rectRight - (threshold.right || 0) >= 0; // Right edge is within the left of the window
83
- if (lastValue !== isVisible) {
84
- setLastValue(isVisible);
85
- onChange(isVisible);
86
- if (isVisible && triggerOnce) {
87
- stopWatching();
88
- }
89
- }
90
- }, [rectDimensions, lastValue, threshold, onChange, triggerOnce, stopWatching]);
42
+ }, [disabled, measureAndNotify]);
43
+
91
44
  return (
92
- <View ref={localRef} {...rest} onLayout={() => measureInnerView()}>
45
+ <View ref={localRef} {...rest} onLayout={measureAndNotify}>
93
46
  {children}
94
47
  </View>
95
48
  );
96
49
  });
50
+
97
51
  export default VisibilitySensor;
@@ -1,31 +1,31 @@
1
1
  interface Resources {
2
2
  componentKey: {
3
- sureKey: "确定";
4
- satisfyKey: "满意";
5
- confirmKey: "确认";
6
- uploadingKey: "上传中";
3
+ sureKey: "確定";
4
+ satisfyKey: "滿意";
5
+ confirmKey: "確認";
6
+ uploadingKey: "上傳中";
7
7
  resetKey: "重置";
8
- NoDataKey: "暂无数据";
8
+ NoDataKey: "暫無數據";
9
9
  liveStreamingKey: "直播";
10
10
  generallyKey: "一般";
11
- uploadFailedKey: "上传失败";
11
+ uploadFailedKey: "上傳失敗";
12
12
  submitKey: "提交";
13
- requestSuccessfulKey: "请求成功";
13
+ requestSuccessfulKey: "請求成功";
14
14
  cancelKey: "取消";
15
- PullDownToRefreshKey: "下拉刷新";
16
- selectAllKey: "全选";
17
- requestDataKey: "请求数据中";
15
+ PullDownToRefreshKey: "下拉重繪";
16
+ selectAllKey: "全選";
17
+ requestDataKey: "請求數據中";
18
18
  closeKey: "收起";
19
- veryBadKey: "极差";
20
- searchKey: "搜索";
21
- expandKey: "展开";
22
- IDCardPhotoKey: "身份证人像面";
19
+ veryBadKey: "極差";
20
+ searchKey: "蒐索";
21
+ expandKey: "展開";
22
+ IDCardPhotoKey: "身份證人像面";
23
23
  finishKey: "完成";
24
- surpriseKey: "惊喜";
25
- releaseRefreshKey: "松开刷新";
24
+ surpriseKey: "驚喜";
25
+ releaseRefreshKey: "鬆開重繪";
26
26
  nationalEmblemSideOfIDCardKey: "身份证国徽面";
27
- buttonKey: "按钮";
28
- jumpKey: "跳转";
27
+ buttonKey: "按鈕";
28
+ jumpKey: "跳轉";
29
29
  disappointmentKey: "失望";
30
30
  };
31
31
  }
@@ -1,35 +1,4 @@
1
1
  {
2
- "zh_cn": {
3
- "componentKey": {
4
- "sureKey": "确定",
5
- "satisfyKey": "满意",
6
- "confirmKey": "确认",
7
- "uploadingKey": "上传中",
8
- "resetKey": "重置",
9
- "NoDataKey": "暂无数据",
10
- "liveStreamingKey": "直播",
11
- "generallyKey": "一般",
12
- "uploadFailedKey": "上传失败",
13
- "submitKey": "提交",
14
- "requestSuccessfulKey": "请求成功",
15
- "cancelKey": "取消",
16
- "PullDownToRefreshKey": "下拉刷新",
17
- "selectAllKey": "全选",
18
- "requestDataKey": "请求数据中",
19
- "closeKey": "收起",
20
- "veryBadKey": "极差",
21
- "searchKey": "搜索",
22
- "expandKey": "展开",
23
- "IDCardPhotoKey": "身份证人像面",
24
- "finishKey": "完成",
25
- "surpriseKey": "惊喜",
26
- "releaseRefreshKey": "松开刷新",
27
- "nationalEmblemSideOfIDCardKey": "身份证国徽面",
28
- "buttonKey": "按钮",
29
- "jumpKey": "跳转",
30
- "disappointmentKey": "失望"
31
- }
32
- },
33
2
  "zh_tw": {
34
3
  "componentKey": {
35
4
  "sureKey": "確定",
@@ -91,5 +60,36 @@
91
60
  "jumpKey": "Jump",
92
61
  "disappointmentKey": "Disappointment"
93
62
  }
63
+ },
64
+ "zh_cn": {
65
+ "componentKey": {
66
+ "sureKey": "确定",
67
+ "satisfyKey": "满意",
68
+ "confirmKey": "确认",
69
+ "uploadingKey": "上传中",
70
+ "resetKey": "重置",
71
+ "NoDataKey": "暂无数据",
72
+ "liveStreamingKey": "直播",
73
+ "generallyKey": "一般",
74
+ "uploadFailedKey": "上传失败",
75
+ "submitKey": "提交",
76
+ "requestSuccessfulKey": "请求成功",
77
+ "cancelKey": "取消",
78
+ "PullDownToRefreshKey": "下拉刷新",
79
+ "selectAllKey": "全选",
80
+ "requestDataKey": "请求数据中",
81
+ "closeKey": "收起",
82
+ "veryBadKey": "极差",
83
+ "searchKey": "搜索",
84
+ "expandKey": "展开",
85
+ "IDCardPhotoKey": "身份证人像面",
86
+ "finishKey": "完成",
87
+ "surpriseKey": "惊喜",
88
+ "releaseRefreshKey": "松开刷新",
89
+ "nationalEmblemSideOfIDCardKey": "身份证国徽面",
90
+ "buttonKey": "按钮",
91
+ "jumpKey": "跳转",
92
+ "disappointmentKey": "失望"
93
+ }
94
94
  }
95
95
  }