Add coexistence checks to all enqueue methods to prevent loading both React and Grid.js assets simultaneously. Changes: - ReactAdmin.php: Only enqueue React assets when ?react=1 - Init.php: Skip Grid.js when React active on admin pages - Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0 - Customer.php, Product.php, License.php: Add coexistence checks Now the toggle between Classic and React versions works correctly. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
262 lines
9.1 KiB
JavaScript
262 lines
9.1 KiB
JavaScript
"use strict";
|
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
var _react = require("react");
|
|
var _reactNative = require("react-native");
|
|
var _reactNativeVideo = _interopRequireDefault(require("react-native-video"));
|
|
var _reactNativeBridge = require("@wordpress/react-native-bridge");
|
|
var _i18n = require("@wordpress/i18n");
|
|
var _components = require("@wordpress/components");
|
|
var _element = require("@wordpress/element");
|
|
var _compose = require("@wordpress/compose");
|
|
var _focalPoint = _interopRequireDefault(require("./focal-point"));
|
|
var _tooltip = _interopRequireDefault(require("./tooltip"));
|
|
var _style = _interopRequireDefault(require("./style.scss"));
|
|
var _utils = require("./utils");
|
|
var _math = require("../utils/math");
|
|
/**
|
|
* External dependencies
|
|
*/
|
|
|
|
/**
|
|
* WordPress dependencies
|
|
*/
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
|
|
const MIN_POSITION_VALUE = 0;
|
|
const MAX_POSITION_VALUE = 100;
|
|
const FOCAL_POINT_UNITS = [{
|
|
default: 50,
|
|
label: '%',
|
|
value: '%'
|
|
}];
|
|
function FocalPointPicker(props) {
|
|
const {
|
|
focalPoint,
|
|
onChange,
|
|
shouldEnableBottomSheetScroll,
|
|
url
|
|
} = props;
|
|
const isVideo = (0, _utils.isVideoType)(url);
|
|
const [containerSize, setContainerSize] = (0, _element.useState)(null);
|
|
const [sliderKey, setSliderKey] = (0, _element.useState)(0);
|
|
const [displayPlaceholder, setDisplayPlaceholder] = (0, _element.useState)(true);
|
|
const [videoNaturalSize, setVideoNaturalSize] = (0, _element.useState)(null);
|
|
const [tooltipVisible, setTooltipVisible] = (0, _element.useState)(false);
|
|
const locationPageOffsetX = (0, _element.useRef)();
|
|
const locationPageOffsetY = (0, _element.useRef)();
|
|
const videoRef = (0, _element.useRef)(null);
|
|
(0, _element.useEffect)(() => {
|
|
(0, _reactNativeBridge.requestFocalPointPickerTooltipShown)(tooltipShown => {
|
|
if (!tooltipShown) {
|
|
setTooltipVisible(true);
|
|
(0, _reactNativeBridge.setFocalPointPickerTooltipShown)(true);
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
// Animated coordinates for drag handle.
|
|
const pan = (0, _element.useRef)(new _reactNative.Animated.ValueXY()).current;
|
|
|
|
/**
|
|
* Set drag handle position anytime focal point coordinates change.
|
|
* E.g. initial render, dragging range sliders.
|
|
*/
|
|
(0, _element.useEffect)(() => {
|
|
if (containerSize) {
|
|
pan.setValue({
|
|
x: focalPoint.x * containerSize.width,
|
|
y: focalPoint.y * containerSize.height
|
|
});
|
|
}
|
|
}, [focalPoint, containerSize, pan]);
|
|
|
|
// Pan responder to manage drag handle interactivity.
|
|
const panResponder = (0, _element.useMemo)(() => _reactNative.PanResponder.create({
|
|
onStartShouldSetPanResponder: () => true,
|
|
onStartShouldSetPanResponderCapture: () => true,
|
|
onMoveShouldSetPanResponder: () => true,
|
|
onMoveShouldSetPanResponderCapture: () => true,
|
|
onPanResponderGrant: event => {
|
|
shouldEnableBottomSheetScroll(false);
|
|
const {
|
|
locationX: x,
|
|
locationY: y,
|
|
pageX,
|
|
pageY
|
|
} = event.nativeEvent;
|
|
locationPageOffsetX.current = pageX - x;
|
|
locationPageOffsetY.current = pageY - y;
|
|
pan.setValue({
|
|
x,
|
|
y
|
|
}); // Set cursor to tap location.
|
|
pan.extractOffset(); // Set offset to current value.
|
|
},
|
|
|
|
// Move cursor to match delta drag.
|
|
onPanResponderMove: _reactNative.Animated.event([null, {
|
|
dx: pan.x,
|
|
dy: pan.y
|
|
}], {
|
|
useNativeDriver: false
|
|
}),
|
|
onPanResponderRelease: event => {
|
|
shouldEnableBottomSheetScroll(true);
|
|
pan.flattenOffset(); // Flatten offset into value.
|
|
const {
|
|
pageX,
|
|
pageY
|
|
} = event.nativeEvent;
|
|
// Ideally, x and y below are merely locationX and locationY from the
|
|
// nativeEvent. However, we are required to compute these relative
|
|
// coordinates to workaround a bug affecting Android's PanResponder.
|
|
// Specifically, dragging the handle outside the bounds of the image
|
|
// results in inaccurate locationX and locationY coordinates to be
|
|
// reported. https://github.com/facebook/react-native/issues/15290#issuecomment-435494944
|
|
const x = pageX - locationPageOffsetX.current;
|
|
const y = pageY - locationPageOffsetY.current;
|
|
onChange({
|
|
x: (0, _math.clamp)(x / containerSize?.width, 0, 1).toFixed(2),
|
|
y: (0, _math.clamp)(y / containerSize?.height, 0, 1).toFixed(2)
|
|
});
|
|
// Slider (child of RangeCell) is uncontrolled, so we must increment a
|
|
// key to re-mount and sync the pan gesture values to the sliders
|
|
// https://github.com/callstack/react-native-slider/tree/v3.0.3#value
|
|
setSliderKey(prevState => prevState + 1);
|
|
}
|
|
}), [containerSize, pan, onChange, shouldEnableBottomSheetScroll]);
|
|
const mediaBackground = (0, _compose.usePreferredColorSchemeStyle)(_style.default.mediaBackground, _style.default.mediaBackgroundDark);
|
|
const imagePreviewStyles = [displayPlaceholder && _style.default.mediaPlaceholder, _style.default.image];
|
|
const videoPreviewStyles = [{
|
|
aspectRatio: videoNaturalSize && videoNaturalSize.width / videoNaturalSize.height,
|
|
// Hide Video component since it has black background while loading the source
|
|
opacity: displayPlaceholder ? 0 : 1
|
|
}, _style.default.video, displayPlaceholder && _style.default.mediaPlaceholder];
|
|
const focalPointGroupStyles = [_style.default.focalPointGroup, {
|
|
transform: [{
|
|
translateX: pan.x.interpolate({
|
|
inputRange: [0, containerSize?.width || 0],
|
|
outputRange: [0, containerSize?.width || 0],
|
|
extrapolate: 'clamp'
|
|
})
|
|
}, {
|
|
translateY: pan.y.interpolate({
|
|
inputRange: [0, containerSize?.height || 0],
|
|
outputRange: [0, containerSize?.height || 0],
|
|
extrapolate: 'clamp'
|
|
})
|
|
}]
|
|
}];
|
|
const FOCAL_POINT_SIZE = 50;
|
|
const focalPointStyles = _reactNative.StyleSheet.flatten([_style.default.focalPoint, {
|
|
height: FOCAL_POINT_SIZE,
|
|
marginLeft: -(FOCAL_POINT_SIZE / 2),
|
|
marginTop: -(FOCAL_POINT_SIZE / 2),
|
|
width: FOCAL_POINT_SIZE
|
|
}]);
|
|
const onTooltipPress = () => setTooltipVisible(false);
|
|
const onMediaLayout = event => {
|
|
const {
|
|
height,
|
|
width
|
|
} = event.nativeEvent.layout;
|
|
if (width !== 0 && height !== 0 && (containerSize?.width !== width || containerSize?.height !== height)) {
|
|
setContainerSize({
|
|
width,
|
|
height
|
|
});
|
|
}
|
|
};
|
|
const onImageDataLoad = () => setDisplayPlaceholder(false);
|
|
const onVideoLoad = event => {
|
|
const {
|
|
height,
|
|
width
|
|
} = event.naturalSize;
|
|
setVideoNaturalSize({
|
|
height,
|
|
width
|
|
});
|
|
setDisplayPlaceholder(false);
|
|
// Avoid invisible, paused video on Android, presumably related to
|
|
// https://github.com/react-native-video/react-native-video/issues/1979
|
|
videoRef?.current.seek(0);
|
|
};
|
|
const onXCoordinateChange = x => onChange({
|
|
x: (x / 100).toFixed(2)
|
|
});
|
|
const onYCoordinateChange = y => onChange({
|
|
y: (y / 100).toFixed(2)
|
|
});
|
|
return (0, _react.createElement)(_reactNative.View, {
|
|
style: _style.default.container
|
|
}, (0, _react.createElement)(_tooltip.default, {
|
|
onPress: onTooltipPress,
|
|
visible: tooltipVisible
|
|
}, (0, _react.createElement)(_reactNative.View, {
|
|
style: [_style.default.media, mediaBackground]
|
|
}, (0, _react.createElement)(_reactNative.View, {
|
|
...panResponder.panHandlers,
|
|
onLayout: onMediaLayout,
|
|
style: _style.default.mediaContainer
|
|
}, !isVideo && (0, _react.createElement)(_components.Image, {
|
|
editButton: false,
|
|
highlightSelected: false,
|
|
isSelected: !displayPlaceholder,
|
|
height: "100%",
|
|
url: url,
|
|
style: imagePreviewStyles,
|
|
onImageDataLoad: onImageDataLoad
|
|
}), isVideo && (0, _react.createElement)(_reactNativeVideo.default, {
|
|
muted: true,
|
|
paused: true,
|
|
disableFocus: true,
|
|
onLoad: onVideoLoad,
|
|
ref: videoRef,
|
|
resizeMode: "contain",
|
|
source: {
|
|
uri: url
|
|
},
|
|
style: videoPreviewStyles
|
|
}), !displayPlaceholder && (0, _react.createElement)(_reactNative.Animated.View, {
|
|
pointerEvents: "none",
|
|
style: focalPointGroupStyles
|
|
}, (0, _react.createElement)(_tooltip.default.Label, {
|
|
text: (0, _i18n.__)('Drag to adjust focal point'),
|
|
yOffset: -(FOCAL_POINT_SIZE / 2)
|
|
}), (0, _react.createElement)(_focalPoint.default, {
|
|
height: focalPointStyles.height,
|
|
style: focalPointStyles,
|
|
testID: "focal-point-picker-handle",
|
|
width: focalPointStyles.width
|
|
})))), (0, _react.createElement)(_components.UnitControl, {
|
|
key: `xAxis-${sliderKey}`,
|
|
label: (0, _i18n.__)('X-Axis Position'),
|
|
max: MAX_POSITION_VALUE,
|
|
min: MIN_POSITION_VALUE,
|
|
onChange: onXCoordinateChange,
|
|
unit: "%",
|
|
units: FOCAL_POINT_UNITS,
|
|
value: Math.round(focalPoint.x * 100)
|
|
}), (0, _react.createElement)(_components.UnitControl, {
|
|
key: `yAxis-${sliderKey}`,
|
|
label: (0, _i18n.__)('Y-Axis Position'),
|
|
max: MAX_POSITION_VALUE,
|
|
min: MIN_POSITION_VALUE,
|
|
onChange: onYCoordinateChange,
|
|
unit: "%",
|
|
units: FOCAL_POINT_UNITS,
|
|
value: Math.round(focalPoint.y * 100)
|
|
})));
|
|
}
|
|
var _default = FocalPointPicker;
|
|
exports.default = _default;
|
|
//# sourceMappingURL=index.native.js.map
|