homegrade_blocks_production/blocks/focused-schema/src/edit.js
Antoine M 0c828ee44d
All checks were successful
continuous-integration/drone/push Build is passing
refining focused-schema to accept overflowing tag and limit bubble placement
2024-10-01 15:29:12 +02:00

312 lines
7.4 KiB
JavaScript

import "./editor.scss";
import "./focus-point";
import { __ } from "@wordpress/i18n";
import { useSelect, dispatch, select } from "@wordpress/data";
import { useEffect, useState } from "@wordpress/element";
import { createBlock } from "@wordpress/blocks";
import {
InnerBlocks,
useBlockProps,
MediaPlaceholder,
BlockControls,
MediaReplaceFlow,
InspectorControls,
} from "@wordpress/block-editor";
import {
ToggleControl,
ToolbarButton,
Spinner,
withNotices,
Button,
PanelBody,
Tip,
} from "@wordpress/components";
import { isBlobURL, revokeBlobURL } from "@wordpress/blob";
import { cover, handle, trash } from "@wordpress/icons";
function Edit({
attributes,
setAttributes,
noticeOperations,
noticeList,
noticeUI,
clientId,
...props
}) {
const {
coverUrl,
coverId,
coverAlt,
showLegend,
coverLegend,
showDescription,
coverDescription,
focusBullets,
} = attributes;
console.log(coverLegend);
const [blobUrl, setBlobUrl] = useState();
const currentBlockDatas = useSelect((select) => {
return select("core/block-editor").getBlocksByClientId(clientId)[0];
});
let children = useSelect(
(select) =>
select("core/block-editor").getBlocksByClientId(clientId)[0].innerBlocks,
);
function onUploadError(message) {
noticeOperations.removeAllNotices(); // Remove all previous notices
noticeOperations.createErrorNotice(message);
}
function removeCoverImg() {
setAttributes({
coverUrl: undefined,
coverId: undefined,
coverDescription: "",
coverLegend: "",
coverAlt: "",
});
}
function updateCover(image) {
if (!image || !image.url) {
setAttributes({
coverUrl: undefined,
coverId: undefined,
coverDescription: "",
coverLegend: "",
coverAlt: "",
});
return;
}
setAttributes({
coverUrl: image.url,
coverId: image.id,
coverAlt: image.alt,
coverDescription: image.description,
coverLegend: image.caption,
});
}
function passCoverUrlToChildren() {
if (children && coverUrl) {
children.forEach(function (child) {
dispatch("core/block-editor").updateBlockAttributes(child.clientId, {
coverUrl: coverUrl,
});
});
}
}
function passIndexToChildren() {
if (children) {
children.forEach((child, index) => {
dispatch("core/block-editor").updateBlockAttributes(child.clientId, {
focusIndex: index + 1,
});
});
}
}
function updateFocusPointBullets() {
if (children) {
const focusBullets = children.map((child, index) => {
return {
title: child.attributes.focusTitle,
x: child.attributes.focusPosition.x,
y: child.attributes.focusPosition.y,
};
});
setAttributes({ focusBullets });
}
}
function insertFocusPointBlock() {
const index = children && children.length ? children.length : 0;
const newBlock = createBlock("homegrade-content-blocks/focus-point", {});
dispatch("core/block-editor").insertBlocks(newBlock, index, clientId);
}
function handleBulletClick(index) {
if (currentBlockDatas && currentBlockDatas.innerBlocks) {
console.log(currentBlockDatas.innerBlocks[index].clientId);
dispatch("core/block-editor").selectBlock(
currentBlockDatas.innerBlocks[index].clientId,
);
}
}
function handleShowDescription() {
setAttributes({ showDescription: !showDescription });
}
function handleShowLegend() {
setAttributes({ showLegend: !showLegend });
}
const renderedFocusPointBullets = focusBullets.map((focusBullet, index) => {
return (
<div
data-focus-bullet-title={focusBullet.title}
className="homegrade-blocks-focus-point-bullet"
style={{
top: `${focusBullet.y * 100}%`,
left: `${focusBullet.x * 100}%`,
}}
onClick={() => handleBulletClick(index)}
>
<span className="homegrade-blocks-focus-point-bullet__index">
{index + 1}
</span>
</div>
);
});
useEffect(() => {
updateFocusPointBullets();
if (!coverId && isBlobURL(coverUrl)) {
setAttributes({ coverUrl: undefined, coverAlt: "" });
}
}, []);
useEffect(() => {
// Fonction de clean du BLOB URL qui se lance à chaque changement de coverUrl
if (isBlobURL(coverUrl)) {
// Si la cover est une blob, c'est que ça upload donc on met cette url dans le state
setBlobUrl(coverUrl);
} else {
// Si la cover en'est plus une blob, c'est que l'upload est terminé, on revoke la blob et on clean le state
revokeBlobURL(blobUrl); // On utilise la valeur stocké dans le state pour revoke l'url
setBlobUrl();
}
passCoverUrlToChildren();
}, [coverUrl]);
useEffect(() => {
updateFocusPointBullets();
passCoverUrlToChildren();
}, [children]);
useEffect(() => {
passIndexToChildren();
}, [currentBlockDatas]);
return (
<>
<InspectorControls>
<PanelBody title="Points de légende">
<Button
variant="primary"
onClick={() => {
insertFocusPointBlock();
}}
>
Ajouter un point Légende
</Button>
</PanelBody>
<PanelBody
title="Source de l'image / Schéma"
className="homegrade-blocks-components-image__panel-body "
>
{coverUrl && <img src={coverUrl} alt={coverAlt} />}
<div className="media-replace-container">
<MediaReplaceFlow
mediaId={coverId}
mediaUrl={coverUrl}
allowedTypes={["image"]}
accept="image/*"
onSelect={updateCover}
name={
!coverUrl
? __("Ajouter", "homegrade-blocks__texte-backoffice")
: __("Remplacer", "homegrade-blocks__texte-backoffice")
}
/>
{coverUrl && (
<div>
<Button
className="custom-flow-button"
variant="primary"
icon={trash}
label="Supprimer"
onClick={removeCoverImg}
/>
</div>
)}
</div>
</PanelBody>
<PanelBody
title="Paramètres"
className="homegrade-blocks-components-image__panel-body "
>
<ToggleControl
label="Afficher la description"
checked={showDescription}
onChange={handleShowDescription}
help="Coché, la description sera ajouté sous l'image"
/>
<ToggleControl
label="Afficher la légende"
checked={showLegend}
onChange={handleShowLegend}
help="Coché, la légende (caption) sera ajouté sous l'image"
/>
</PanelBody>
</InspectorControls>
<MediaPlaceholder
disableMediaButtons={coverUrl}
icon="admin-appearance"
onSelect={updateCover}
onError={onUploadError}
accept="image/*" // On upload Allow only images
allowedTypes={["image"]} // Onlibrary Allow only images
notices={noticeUI} // En cas d'erreur d'upload
/>
<section
{...useBlockProps({
className: `homegrade-blocks-focused-schema`,
})}
>
{coverUrl && (
<figure
className={`picture-container ${
isBlobURL(coverUrl) ? "is-loading" : ""
}`}
>
<img
src={coverUrl}
alt={coverAlt}
data-description={coverDescription}
data-legend={coverLegend}
/>
{renderedFocusPointBullets}
{isBlobURL(coverUrl) && <Spinner />}
</figure>
)}
<figcaption>
<p className="description-legend">
{showLegend && coverLegend && (
<span className="legend">{coverLegend}</span>
)}
{showDescription && coverDescription && (
<span className="description">{coverDescription}</span>
)}
</p>
<ol>
<InnerBlocks
allowedBlocks={["homegrade-content-blocks/focus-point"]}
/>
</ol>
</figcaption>
</section>
</>
);
}
export default withNotices(Edit);