@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.
- package/coverage/.tmp/coverage-1.json +1 -1
- package/coverage/.tmp/coverage-10.json +1 -1
- package/coverage/.tmp/coverage-11.json +1 -1
- package/coverage/.tmp/coverage-12.json +1 -1
- package/coverage/.tmp/coverage-13.json +1 -1
- package/coverage/.tmp/coverage-14.json +1 -1
- package/coverage/.tmp/coverage-15.json +1 -1
- package/coverage/.tmp/coverage-16.json +1 -1
- package/coverage/.tmp/coverage-17.json +1 -1
- package/coverage/.tmp/coverage-18.json +1 -1
- package/coverage/.tmp/coverage-19.json +1 -1
- package/coverage/.tmp/coverage-2.json +1 -1
- package/coverage/.tmp/coverage-20.json +1 -1
- package/coverage/.tmp/coverage-21.json +1 -1
- package/coverage/.tmp/coverage-22.json +1 -1
- package/coverage/.tmp/coverage-23.json +1 -1
- package/coverage/.tmp/coverage-24.json +1 -1
- package/coverage/.tmp/coverage-25.json +1 -1
- package/coverage/.tmp/coverage-26.json +1 -1
- package/coverage/.tmp/coverage-27.json +1 -1
- package/coverage/.tmp/coverage-28.json +1 -1
- package/coverage/.tmp/coverage-29.json +1 -1
- package/coverage/.tmp/coverage-3.json +1 -1
- package/coverage/.tmp/coverage-30.json +1 -1
- package/coverage/.tmp/coverage-31.json +1 -1
- package/coverage/.tmp/coverage-32.json +1 -1
- package/coverage/.tmp/coverage-33.json +1 -1
- package/coverage/.tmp/coverage-35.json +1 -1
- package/coverage/.tmp/coverage-36.json +1 -1
- package/coverage/.tmp/coverage-37.json +1 -1
- package/coverage/.tmp/coverage-38.json +1 -1
- package/coverage/.tmp/coverage-4.json +1 -1
- package/coverage/.tmp/coverage-5.json +1 -1
- package/coverage/.tmp/coverage-6.json +1 -1
- package/coverage/.tmp/coverage-7.json +1 -1
- package/coverage/.tmp/coverage-8.json +1 -1
- package/coverage/.tmp/coverage-9.json +1 -1
- package/lib/cjs/components/Image/VisibilitySensor.js +20 -73
- package/lib/cjs/components/Image/VisibilitySensor.js.map +1 -1
- package/lib/esm/components/Image/VisibilitySensor.js +22 -75
- package/lib/esm/components/Image/VisibilitySensor.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Image/VisibilitySensor.tsx +35 -81
- package/src/i18n/@types/resources.d.ts +18 -18
- 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,
|
|
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,
|
|
2
|
-
import React, { forwardRef, useRef, useImperativeHandle,
|
|
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
|
-
|
|
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
|
|
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
|
|
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 (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
40
|
+
if (!disabled && !measuredOnceRef.current) {
|
|
41
|
+
requestAnimationFrame(function () {
|
|
42
|
+
return measureAndNotify();
|
|
43
|
+
});
|
|
71
44
|
}
|
|
72
|
-
|
|
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:
|
|
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,
|
|
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,97 +1,51 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useRef,
|
|
2
|
-
import { Dimensions,
|
|
3
|
-
import type { VisibilitySensorRef, VisibilitySensorProps
|
|
4
|
-
|
|
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
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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
|
-
|
|
66
|
-
|
|
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
|
-
|
|
69
|
-
|
|
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={
|
|
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
|
}
|
package/src/i18n/index.json
CHANGED
|
@@ -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
|
}
|