homegrade_blocks_production/blocks/focused-schema/src/edit.js

248 lines
5.9 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 {
useBlockProps,
MediaPlaceholder,
BlockControls,
MediaReplaceFlow,
InspectorControls,
} from "@wordpress/block-editor";
import {
ToolbarButton,
Spinner,
withNotices,
Button,
PanelBody,
} from "@wordpress/components";
import { InnerBlocks } from "@wordpress/block-editor";
import { isBlobURL, revokeBlobURL } from "@wordpress/blob";
function Edit({
attributes,
setAttributes,
noticeOperations,
noticeList,
noticeUI,
clientId,
...props
}) {
const { coverUrl, coverId, coverAlt, focusBullets } = attributes;
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,
coverAlt: "",
});
}
function updateImage(image) {
if (!image || !image.url) {
setAttributes({
coverUrl: undefined,
coverId: undefined,
coverAlt: "",
});
return;
}
setAttributes({
coverUrl: image.url,
coverId: image.id,
coverAlt: image.alt,
});
}
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
);
}
}
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>
<Button
variant="primary"
onClick={() => {
insertFocusPointBlock();
}}
>
Ajouter un point Légende
</Button>
</PanelBody>
</InspectorControls>
<BlockControls>
{coverUrl && (
<>
<MediaReplaceFlow
group="inline"
name="Remplacer l'image"
disableMediaButtons={coverUrl}
icon="trash"
onSelect={updateImage}
onError={onUploadError}
accept="image/*" // On upload Allow only images
allowedTypes={["image"]} // Onlibrary Allow only images
notices={noticeUI} // En cas d'erreur d'upload
mediaId={coverId}
mediaURL={coverUrl}
className="media-button-replacer"
/>
<ToolbarButton
icon={"trash"}
title="Supprimer l'image"
onClick={removeCoverImg}
/>
</>
)}
</BlockControls>
<MediaPlaceholder
disableMediaButtons={coverUrl}
icon="admin-appearance"
onSelect={updateImage}
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} />
{renderedFocusPointBullets}
{isBlobURL(coverUrl) && <Spinner />}
</figure>
)}
<figcaption>
<ol>
<InnerBlocks
allowedBlocks={["homegrade-content-blocks/focus-point"]}
/>
</ol>
</figcaption>
</section>
</>
);
}
export default withNotices(Edit);