UNPKG

@gechiui/block-editor

Version:
383 lines (347 loc) 13.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _element = require("@gechiui/element"); var _reactNative = require("react-native"); var _lodash = require("lodash"); var _components = require("@gechiui/components"); var _blocks = require("@gechiui/blocks"); var _i18n = require("@gechiui/i18n"); var _data = require("@gechiui/data"); var _compose = require("@gechiui/compose"); var _icons = require("@gechiui/icons"); var _notices = require("@gechiui/notices"); var _reusableBlocks = require("@gechiui/reusable-blocks"); var _coreData = require("@gechiui/core-data"); var _moverDescription = require("../block-mover/mover-description"); var _store = require("../../store"); var _blockTransformationsMenu = _interopRequireDefault(require("../block-switcher/block-transformations-menu")); /** * External dependencies */ /** * GeChiUI dependencies */ /** * Internal dependencies */ const BlockActionsMenu = _ref => { let { // Select blockTitle, canInsertBlockType, getBlocksByClientId, isEmptyDefaultBlock, isLocked, canDuplicate, isFirst, isLast, isReusableBlockType, reusableBlock, rootClientId, selectedBlockClientId, selectedBlockPossibleTransformations, // Dispatch createSuccessNotice, convertToRegularBlocks, duplicateBlock, onMoveDown, onMoveUp, openGeneralSidebar, pasteBlock, removeBlocks, // Passed in anchorNodeRef, isStackedHorizontally, onDelete, wrapBlockMover, wrapBlockSettings } = _ref; const [clipboard, setCurrentClipboard] = (0, _element.useState)((0, _components.getClipboard)()); const blockActionsMenuPickerRef = (0, _element.useRef)(); const blockTransformationMenuPickerRef = (0, _element.useRef)(); const moversOptions = { keys: ['icon', 'actionTitle'] }; const clipboardBlock = clipboard && (0, _blocks.rawHandler)({ HTML: clipboard })[0]; const isPasteEnabled = clipboardBlock && canInsertBlockType(clipboardBlock.name, rootClientId); const { actionTitle: { backward: backwardButtonTitle, forward: forwardButtonTitle } } = (0, _moverDescription.getMoversSetup)(isStackedHorizontally, moversOptions); const allOptions = { settings: { id: 'settingsOption', label: (0, _i18n.__)('Block settings'), value: 'settingsOption', onSelect: openGeneralSidebar }, backwardButton: { id: 'backwardButtonOption', label: backwardButtonTitle, value: 'backwardButtonOption', disabled: isFirst, onSelect: onMoveUp }, forwardButton: { id: 'forwardButtonOption', label: forwardButtonTitle, value: 'forwardButtonOption', disabled: isLast, onSelect: onMoveDown }, delete: { id: 'deleteOption', label: (0, _i18n.__)('Remove block'), value: 'deleteOption', separated: true, disabled: isEmptyDefaultBlock, onSelect: () => { onDelete(); createSuccessNotice( // translators: displayed right after the block is removed. (0, _i18n.__)('Block removed')); } }, transformButton: { id: 'transformButtonOption', label: (0, _i18n.__)('Transform block…'), value: 'transformButtonOption', onSelect: () => { if (blockTransformationMenuPickerRef.current) { blockTransformationMenuPickerRef.current.presentPicker(); } } }, copyButton: { id: 'copyButtonOption', label: (0, _i18n.__)('Copy block'), value: 'copyButtonOption', onSelect: () => { const serializedBlock = (0, _blocks.serialize)(getBlocksByClientId(selectedBlockClientId)); setCurrentClipboard(serializedBlock); (0, _components.setClipboard)(serializedBlock); createSuccessNotice( // translators: displayed right after the block is copied. (0, _i18n.__)('Block copied')); } }, cutButton: { id: 'cutButtonOption', label: (0, _i18n.__)('Cut block'), value: 'cutButtonOption', onSelect: () => { (0, _components.setClipboard)((0, _blocks.serialize)(getBlocksByClientId(selectedBlockClientId))); removeBlocks(selectedBlockClientId); createSuccessNotice( // translators: displayed right after the block is cut. (0, _i18n.__)('Block cut')); } }, pasteButton: { id: 'pasteButtonOption', label: (0, _i18n.__)('Paste block after'), value: 'pasteButtonOption', onSelect: () => { onPasteBlock(); createSuccessNotice( // translators: displayed right after the block is pasted. (0, _i18n.__)('Block pasted')); } }, duplicateButton: { id: 'duplicateButtonOption', label: (0, _i18n.__)('Duplicate block'), value: 'duplicateButtonOption', onSelect: () => { duplicateBlock(); createSuccessNotice( // translators: displayed right after the block is duplicated. (0, _i18n.__)('Block duplicated')); } }, convertToRegularBlocks: { id: 'convertToRegularBlocksOption', label: (0, _i18n.__)('转换为常规区块'), value: 'convertToRegularBlocksOption', onSelect: () => { var _reusableBlock$title; createSuccessNotice((0, _i18n.sprintf)( /* translators: %s: name of the reusable block */ (0, _i18n.__)('%s converted to regular blocks'), (reusableBlock === null || reusableBlock === void 0 ? void 0 : (_reusableBlock$title = reusableBlock.title) === null || _reusableBlock$title === void 0 ? void 0 : _reusableBlock$title.raw) || blockTitle)); convertToRegularBlocks(); } } }; const options = (0, _lodash.compact)([wrapBlockMover && allOptions.backwardButton, wrapBlockMover && allOptions.forwardButton, wrapBlockSettings && allOptions.settings, !isLocked && selectedBlockPossibleTransformations.length && allOptions.transformButton, canDuplicate && allOptions.copyButton, canDuplicate && allOptions.cutButton, canDuplicate && isPasteEnabled && allOptions.pasteButton, canDuplicate && allOptions.duplicateButton, isReusableBlockType && allOptions.convertToRegularBlocks, !isLocked && allOptions.delete]); // End early if there are no options to show. if (!options.length) { return (0, _element.createElement)(_components.ToolbarButton, { title: (0, _i18n.__)('Open Block Actions Menu'), icon: _icons.moreHorizontalMobile, disabled: true }); } function onPasteBlock() { if (!clipboard) { return; } pasteBlock((0, _blocks.rawHandler)({ HTML: clipboard })[0]); } function onPickerSelect(value) { const selectedItem = options.find(item => item.value === value); selectedItem.onSelect(); } function onPickerPresent() { if (blockActionsMenuPickerRef.current) { blockActionsMenuPickerRef.current.presentPicker(); } } const disabledButtonIndices = options.map((option, index) => option.disabled && index + 1).filter(Boolean); const accessibilityHint = _reactNative.Platform.OS === 'ios' ? (0, _i18n.__)('Double tap to open Action Sheet with available options') : (0, _i18n.__)('Double tap to open Bottom Sheet with available options'); const getAnchor = () => anchorNodeRef ? (0, _reactNative.findNodeHandle)(anchorNodeRef) : undefined; return (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_components.ToolbarButton, { title: (0, _i18n.__)('Open Block Actions Menu'), onClick: onPickerPresent, icon: _icons.moreHorizontalMobile, extraProps: { hint: accessibilityHint } }), (0, _element.createElement)(_components.Picker, { ref: blockActionsMenuPickerRef, options: options, onChange: onPickerSelect, destructiveButtonIndex: options.length, disabledButtonIndices: disabledButtonIndices, hideCancelButton: _reactNative.Platform.OS !== 'ios', leftAlign: true, getAnchor: getAnchor // translators: %s: block title e.g: "Paragraph". , title: (0, _i18n.sprintf)((0, _i18n.__)('%s block options'), blockTitle) }), (0, _element.createElement)(_blockTransformationsMenu.default, { anchorNodeRef: anchorNodeRef, blockTitle: blockTitle, pickerRef: blockTransformationMenuPickerRef, possibleTransformations: selectedBlockPossibleTransformations, selectedBlock: getBlocksByClientId(selectedBlockClientId), selectedBlockClientId: selectedBlockClientId })); }; var _default = (0, _compose.compose)((0, _data.withSelect)((select, _ref2) => { let { clientIds } = _ref2; const { getBlockIndex, getBlockRootClientId, getBlockOrder, getBlockName, getBlockTransformItems, getBlock, getBlocksByClientId, getSelectedBlockClientIds, canInsertBlockType, getTemplateLock } = select(_store.store); const normalizedClientIds = (0, _lodash.castArray)(clientIds); const block = getBlock(normalizedClientIds); const blockName = getBlockName(normalizedClientIds); const blockType = (0, _blocks.getBlockType)(blockName); const blockTitle = blockType === null || blockType === void 0 ? void 0 : blockType.title; const firstClientId = (0, _lodash.first)(normalizedClientIds); const rootClientId = getBlockRootClientId(firstClientId); const blockOrder = getBlockOrder(rootClientId); const firstIndex = getBlockIndex(firstClientId); const lastIndex = getBlockIndex((0, _lodash.last)(normalizedClientIds)); const innerBlocks = getBlocksByClientId(clientIds); const canDuplicate = (0, _lodash.every)(innerBlocks, innerBlock => { return !!innerBlock && (0, _blocks.hasBlockSupport)(innerBlock.name, 'multiple', true) && canInsertBlockType(innerBlock.name, rootClientId); }); const isDefaultBlock = blockName === (0, _blocks.getDefaultBlockName)(); const isEmptyContent = (block === null || block === void 0 ? void 0 : block.attributes.content) === ''; const isExactlyOneBlock = blockOrder.length === 1; const isEmptyDefaultBlock = isExactlyOneBlock && isDefaultBlock && isEmptyContent; const isLocked = !!getTemplateLock(rootClientId); const selectedBlockClientId = (0, _lodash.first)(getSelectedBlockClientIds()); const selectedBlock = selectedBlockClientId ? (0, _lodash.first)(getBlocksByClientId(selectedBlockClientId)) : undefined; const selectedBlockPossibleTransformations = selectedBlock ? getBlockTransformItems([selectedBlock], rootClientId) : []; const isReusableBlockType = block ? (0, _blocks.isReusableBlock)(block) : false; const reusableBlock = isReusableBlockType ? select(_coreData.store).getEntityRecord('postType', 'gc_block', block === null || block === void 0 ? void 0 : block.attributes.ref) : undefined; return { blockTitle, canInsertBlockType, currentIndex: firstIndex, getBlocksByClientId, isEmptyDefaultBlock, isLocked, canDuplicate, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, isReusableBlockType, reusableBlock, rootClientId, selectedBlockClientId, selectedBlockPossibleTransformations }; }), (0, _data.withDispatch)((dispatch, _ref3, _ref4) => { let { clientIds, rootClientId, currentIndex, selectedBlockClientId } = _ref3; let { select } = _ref4; const { moveBlocksDown, moveBlocksUp, duplicateBlocks, removeBlocks, insertBlock, replaceBlocks, clearSelectedBlock } = dispatch(_store.store); const { openGeneralSidebar } = dispatch('core/edit-post'); const { getBlockSelectionEnd, getBlock } = select(_store.store); const { createSuccessNotice } = dispatch(_notices.store); const { __experimentalConvertBlockToStatic: convertBlockToStatic } = dispatch(_reusableBlocks.store); return { createSuccessNotice, convertToRegularBlocks() { clearSelectedBlock(); // Convert action is executed at the end of the current JavaScript execution block // to prevent issues related to undo/redo actions. setImmediate(() => convertBlockToStatic(selectedBlockClientId)); }, duplicateBlock() { return duplicateBlocks(clientIds); }, onMoveDown: (0, _lodash.partial)(moveBlocksDown, clientIds, rootClientId), onMoveUp: (0, _lodash.partial)(moveBlocksUp, clientIds, rootClientId), openGeneralSidebar: () => openGeneralSidebar('edit-post/block'), pasteBlock: clipboardBlock => { const canReplaceBlock = (0, _blocks.isUnmodifiedDefaultBlock)(getBlock(getBlockSelectionEnd())); if (!canReplaceBlock) { const insertedBlock = (0, _blocks.createBlock)(clipboardBlock.name, clipboardBlock.attributes, clipboardBlock.innerBlocks); insertBlock(insertedBlock, currentIndex + 1, rootClientId); } else { replaceBlocks(clientIds, clipboardBlock); } }, removeBlocks }; }), _compose.withInstanceId)(BlockActionsMenu); exports.default = _default; //# sourceMappingURL=block-actions-menu.native.js.map