carhop__plugins__PROD-DEV/plugins/dynamiques-thumbnail-focal-point/src/focal-point-inline.js
Antoine M 17811c8091
All checks were successful
continuous-integration/drone/push Build is passing
FEATURE Introducing the thumbnail focal point plugin with its features
2025-10-16 11:47:35 +02:00

177 lines
5.6 KiB
JavaScript

import { render, useState, useEffect } from "@wordpress/element";
import { FocalPointPicker } from "@wordpress/components";
import apiFetch from "@wordpress/api-fetch";
const InlineFocalPointPicker = ({ postId, thumbnailUrl, initialFocalPoint }) => {
const [focalPoint, setFocalPoint] = useState(initialFocalPoint);
// Mettre à jour les champs cachés pour la sauvegarde
useEffect(() => {
// Créer ou mettre à jour les champs cachés
let inputX = document.getElementById("thumbnail_focal_point_x");
let inputY = document.getElementById("thumbnail_focal_point_y");
let inputNonce = document.getElementById("thumbnail_focal_point_nonce");
if (!inputX) {
inputX = document.createElement("input");
inputX.type = "hidden";
inputX.name = "thumbnail_focal_point_x";
inputX.id = "thumbnail_focal_point_x";
document.querySelector("form#post").appendChild(inputX);
}
if (!inputY) {
inputY = document.createElement("input");
inputY.type = "hidden";
inputY.name = "thumbnail_focal_point_y";
inputY.id = "thumbnail_focal_point_y";
document.querySelector("form#post").appendChild(inputY);
}
if (!inputNonce) {
inputNonce = document.createElement("input");
inputNonce.type = "hidden";
inputNonce.name = "thumbnail_focal_point_nonce";
inputNonce.id = "thumbnail_focal_point_nonce";
inputNonce.value = window.thumbnailFocalPointData?.nonce || "";
document.querySelector("form#post").appendChild(inputNonce);
}
inputX.value = focalPoint.x;
inputY.value = focalPoint.y;
}, [focalPoint]);
const handleChange = (newFocalPoint) => {
setFocalPoint(newFocalPoint);
};
return (
<div style={{ marginTop: "15px", paddingTop: "15px", borderTop: "1px solid #dcdcde" }}>
<div style={{ marginBottom: "10px" }}>
<strong style={{ fontSize: "13px", color: "#1d2327" }}>Point focal de recadrage</strong>
</div>
<p style={{ marginBottom: "12px", fontSize: "12px", color: "#646970", marginTop: "8px" }}>
Cliquez sur l'image pour définir le point focal utilisé lors du recadrage.
</p>
<div style={{ marginBottom: "10px" }}>
<FocalPointPicker url={thumbnailUrl} value={focalPoint} onChange={handleChange} />
</div>
<p style={{ fontSize: "12px", color: "#646970", marginTop: "8px" }}>
Position :{" "}
<strong style={{ color: "#2271b1" }}>
{Math.round(focalPoint.x * 100)}% / {Math.round(focalPoint.y * 100)}%
</strong>
</p>
</div>
);
};
// Fonction pour injecter le focal point picker dans la meta box de thumbnail
function injectFocalPointPicker() {
// Attendre que la meta box de thumbnail soit chargée
const thumbnailDiv = document.getElementById("postimagediv");
if (!thumbnailDiv) {
return;
}
// Chercher le lien de la thumbnail pour vérifier qu'il y a une image
const thumbnailLink = thumbnailDiv.querySelector("#set-post-thumbnail");
if (!thumbnailLink || !window.thumbnailFocalPointData) {
return;
}
// Vérifier s'il y a une image
const hasImage = thumbnailLink.querySelector("img");
if (!hasImage) {
return;
}
// Créer le conteneur pour notre composant React
let container = document.getElementById("thumbnail-focal-point-inline-root");
if (!container) {
container = document.createElement("div");
container.id = "thumbnail-focal-point-inline-root";
// Trouver la div inside qui contient le contenu
const insideDiv = thumbnailDiv.querySelector(".inside");
if (insideDiv) {
// Injecter après tous les enfants existants de .inside
insideDiv.appendChild(container);
} else {
// Fallback : injecter directement dans postimagediv
thumbnailDiv.appendChild(container);
}
}
const { postId, thumbnailUrl, focalPointX, focalPointY } = window.thumbnailFocalPointData;
// Render le composant React
render(
<InlineFocalPointPicker
postId={postId}
thumbnailUrl={thumbnailUrl}
initialFocalPoint={{ x: focalPointX, y: focalPointY }}
/>,
container
);
}
// Initialiser quand le DOM est prêt
window.addEventListener("DOMContentLoaded", () => {
injectFocalPointPicker();
// Écouter l'événement AJAX de WordPress pour le changement de featured image
if (typeof jQuery !== "undefined") {
jQuery(document).on("ajaxSuccess", function (event, xhr, settings) {
// Vérifier si c'est l'AJAX de set featured image
if (
settings.data &&
typeof settings.data === "string" &&
settings.data.indexOf("action=set-post-thumbnail") !== -1
) {
// WordPress a sauvegardé la nouvelle thumbnail, on peut recharger
setTimeout(() => {
location.reload();
}, 300);
}
});
// Écouter aussi la suppression de thumbnail
jQuery(document).on("click", "#remove-post-thumbnail", function () {
setTimeout(() => {
location.reload();
}, 500);
});
}
});
// Hook dans la media library pour détecter quand une image est sélectionnée
if (typeof wp !== "undefined" && wp.media) {
// Stocker la référence du frame original
const originalFeaturedImage = wp.media.featuredImage;
if (originalFeaturedImage && originalFeaturedImage.frame) {
const originalFrame = originalFeaturedImage.frame;
// Remplacer la méthode frame
wp.media.featuredImage.frame = function () {
if (this._frame) return this._frame;
this._frame = originalFrame.apply(this, arguments);
// Écouter la sélection dans le frame
this._frame.on("select", function () {
// L'utilisateur a sélectionné une image
// Ne rien faire ici, on attend l'AJAX success
});
return this._frame;
};
}
}