"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.MediaPlaceholder = MediaPlaceholder;
exports.default = void 0;
var _clsx = _interopRequireDefault(require("clsx"));
var _components = require("@wordpress/components");
var _i18n = require("@wordpress/i18n");
var _element = require("@wordpress/element");
var _data = require("@wordpress/data");
var _icons = require("@wordpress/icons");
var _blocks2 = require("@wordpress/blocks");
var _deprecated = _interopRequireDefault(require("@wordpress/deprecated"));
var _mediaUpload = _interopRequireDefault(require("../media-upload"));
var _check = _interopRequireDefault(require("../media-upload/check"));
var _urlPopover = _interopRequireDefault(require("../url-popover"));
var _store = require("../../store");
var _jsxRuntime = require("react/jsx-runtime");
/**
 * External dependencies
 */

/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

const noop = () => {};
const InsertFromURLPopover = ({
  src,
  onChange,
  onSubmit,
  onClose,
  popoverAnchor
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_urlPopover.default, {
  anchor: popoverAnchor,
  onClose: onClose,
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("form", {
    className: "block-editor-media-placeholder__url-input-form",
    onSubmit: onSubmit,
    children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
      className: "block-editor-media-placeholder__url-input-field",
      type: "text",
      "aria-label": (0, _i18n.__)('URL'),
      placeholder: (0, _i18n.__)('Paste or type URL'),
      onChange: onChange,
      value: src
    }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
      className: "block-editor-media-placeholder__url-input-submit-button",
      icon: _icons.keyboardReturn,
      label: (0, _i18n.__)('Apply'),
      type: "submit"
    })]
  })
});
const URLSelectionUI = ({
  src,
  onChangeSrc,
  onSelectURL
}) => {
  // Use internal state instead of a ref to make sure that the component
  // re-renders when the popover's anchor updates.
  const [popoverAnchor, setPopoverAnchor] = (0, _element.useState)(null);
  const [isURLInputVisible, setIsURLInputVisible] = (0, _element.useState)(false);
  const openURLInput = () => {
    setIsURLInputVisible(true);
  };
  const closeURLInput = () => {
    setIsURLInputVisible(false);
    popoverAnchor?.focus();
  };
  const onSubmitSrc = event => {
    event.preventDefault();
    if (src && onSelectURL) {
      onSelectURL(src);
      closeURLInput();
    }
  };
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
    className: "block-editor-media-placeholder__url-input-container",
    children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
      className: "block-editor-media-placeholder__button",
      onClick: openURLInput,
      isPressed: isURLInputVisible,
      variant: "secondary",
      "aria-haspopup": "dialog",
      ref: setPopoverAnchor,
      children: (0, _i18n.__)('Insert from URL')
    }), isURLInputVisible && /*#__PURE__*/(0, _jsxRuntime.jsx)(InsertFromURLPopover, {
      src: src,
      onChange: onChangeSrc,
      onSubmit: onSubmitSrc,
      onClose: closeURLInput,
      popoverAnchor: popoverAnchor
    })]
  });
};
function MediaPlaceholder({
  value = {},
  allowedTypes,
  className,
  icon,
  labels = {},
  mediaPreview,
  notices,
  isAppender,
  accept,
  addToGallery,
  multiple = false,
  handleUpload = true,
  disableDropZone,
  disableMediaButtons,
  onError,
  onSelect,
  onCancel,
  onSelectURL,
  onToggleFeaturedImage,
  onDoubleClick,
  onFilesPreUpload = noop,
  onHTMLDrop: deprecatedOnHTMLDrop,
  children,
  mediaLibraryButton,
  placeholder,
  style
}) {
  if (deprecatedOnHTMLDrop) {
    (0, _deprecated.default)('wp.blockEditor.MediaPlaceholder onHTMLDrop prop', {
      since: '6.2',
      version: '6.4'
    });
  }
  const mediaUpload = (0, _data.useSelect)(select => {
    const {
      getSettings
    } = select(_store.store);
    return getSettings().mediaUpload;
  }, []);
  const [src, setSrc] = (0, _element.useState)('');
  (0, _element.useEffect)(() => {
    var _value$src;
    setSrc((_value$src = value?.src) !== null && _value$src !== void 0 ? _value$src : '');
  }, [value?.src]);
  const onlyAllowsImages = () => {
    if (!allowedTypes || allowedTypes.length === 0) {
      return false;
    }
    return allowedTypes.every(allowedType => allowedType === 'image' || allowedType.startsWith('image/'));
  };
  const onChangeSrc = event => {
    setSrc(event.target.value);
  };
  const onFilesUpload = files => {
    if (!handleUpload) {
      return onSelect(files);
    }
    onFilesPreUpload(files);
    let setMedia;
    if (multiple) {
      if (addToGallery) {
        // Since the setMedia function runs multiple times per upload group
        // and is passed newMedia containing every item in its group each time, we must
        // filter out whatever this upload group had previously returned to the
        // gallery before adding and returning the image array with replacement newMedia
        // values.

        // Define an array to store urls from newMedia between subsequent function calls.
        let lastMediaPassed = [];
        setMedia = newMedia => {
          // Remove any images this upload group is responsible for (lastMediaPassed).
          // Their replacements are contained in newMedia.
          const filteredMedia = (value !== null && value !== void 0 ? value : []).filter(item => {
            // If Item has id, only remove it if lastMediaPassed has an item with that id.
            if (item.id) {
              return !lastMediaPassed.some(
              // Be sure to convert to number for comparison.
              ({
                id
              }) => Number(id) === Number(item.id));
            }
            // Compare transient images via .includes since gallery may append extra info onto the url.
            return !lastMediaPassed.some(({
              urlSlug
            }) => item.url.includes(urlSlug));
          });
          // Return the filtered media array along with newMedia.
          onSelect(filteredMedia.concat(newMedia));
          // Reset lastMediaPassed and set it with ids and urls from newMedia.
          lastMediaPassed = newMedia.map(media => {
            // Add everything up to '.fileType' to compare via .includes.
            const cutOffIndex = media.url.lastIndexOf('.');
            const urlSlug = media.url.slice(0, cutOffIndex);
            return {
              id: media.id,
              urlSlug
            };
          });
        };
      } else {
        setMedia = onSelect;
      }
    } else {
      setMedia = ([media]) => onSelect(media);
    }
    mediaUpload({
      allowedTypes,
      filesList: files,
      onFileChange: setMedia,
      onError
    });
  };
  async function handleBlocksDrop(blocks) {
    if (!blocks || !Array.isArray(blocks)) {
      return;
    }
    function recursivelyFindMediaFromBlocks(_blocks) {
      return _blocks.flatMap(block => (block.name === 'core/image' || block.name === 'core/audio' || block.name === 'core/video') && block.attributes.url ? [block] : recursivelyFindMediaFromBlocks(block.innerBlocks));
    }
    const mediaBlocks = recursivelyFindMediaFromBlocks(blocks);
    if (!mediaBlocks.length) {
      return;
    }
    const uploadedMediaList = await Promise.all(mediaBlocks.map(block => block.attributes.id ? block.attributes : new Promise((resolve, reject) => {
      window.fetch(block.attributes.url).then(response => response.blob()).then(blob => mediaUpload({
        filesList: [blob],
        additionalData: {
          title: block.attributes.title,
          alt_text: block.attributes.alt,
          caption: block.attributes.caption
        },
        onFileChange: ([media]) => {
          if (media.id) {
            resolve(media);
          }
        },
        allowedTypes,
        onError: reject
      })).catch(() => resolve(block.attributes.url));
    }))).catch(err => onError(err));
    if (multiple) {
      onSelect(uploadedMediaList);
    } else {
      onSelect(uploadedMediaList[0]);
    }
  }
  async function onHTMLDrop(HTML) {
    const blocks = (0, _blocks2.pasteHandler)({
      HTML
    });
    return await handleBlocksDrop(blocks);
  }
  const onUpload = event => {
    onFilesUpload(event.target.files);
  };
  const defaultRenderPlaceholder = content => {
    let {
      instructions,
      title
    } = labels;
    if (!mediaUpload && !onSelectURL) {
      instructions = (0, _i18n.__)('To edit this block, you need permission to upload media.');
    }
    if (instructions === undefined || title === undefined) {
      const typesAllowed = allowedTypes !== null && allowedTypes !== void 0 ? allowedTypes : [];
      const [firstAllowedType] = typesAllowed;
      const isOneType = 1 === typesAllowed.length;
      const isAudio = isOneType && 'audio' === firstAllowedType;
      const isImage = isOneType && 'image' === firstAllowedType;
      const isVideo = isOneType && 'video' === firstAllowedType;
      if (instructions === undefined && mediaUpload) {
        instructions = (0, _i18n.__)('Upload a media file or pick one from your media library.');
        if (isAudio) {
          instructions = (0, _i18n.__)('Upload an audio file, pick one from your media library, or add one with a URL.');
        } else if (isImage) {
          instructions = (0, _i18n.__)('Upload an image file, pick one from your media library, or add one with a URL.');
        } else if (isVideo) {
          instructions = (0, _i18n.__)('Upload a video file, pick one from your media library, or add one with a URL.');
        }
      }
      if (title === undefined) {
        title = (0, _i18n.__)('Media');
        if (isAudio) {
          title = (0, _i18n.__)('Audio');
        } else if (isImage) {
          title = (0, _i18n.__)('Image');
        } else if (isVideo) {
          title = (0, _i18n.__)('Video');
        }
      }
    }
    const placeholderClassName = (0, _clsx.default)('block-editor-media-placeholder', className, {
      'is-appender': isAppender
    });
    return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.Placeholder, {
      icon: icon,
      label: title,
      instructions: instructions,
      className: placeholderClassName,
      notices: notices,
      onDoubleClick: onDoubleClick,
      preview: mediaPreview,
      style: style,
      children: [content, children]
    });
  };
  const renderPlaceholder = placeholder !== null && placeholder !== void 0 ? placeholder : defaultRenderPlaceholder;
  const renderDropZone = () => {
    if (disableDropZone) {
      return null;
    }
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.DropZone, {
      onFilesDrop: onFilesUpload,
      onHTMLDrop: onHTMLDrop
    });
  };
  const renderCancelLink = () => {
    return onCancel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
      className: "block-editor-media-placeholder__cancel-button",
      title: (0, _i18n.__)('Cancel'),
      variant: "link",
      onClick: onCancel,
      children: (0, _i18n.__)('Cancel')
    });
  };
  const renderUrlSelectionUI = () => {
    return onSelectURL && /*#__PURE__*/(0, _jsxRuntime.jsx)(URLSelectionUI, {
      src: src,
      onChangeSrc: onChangeSrc,
      onSelectURL: onSelectURL
    });
  };
  const renderFeaturedImageToggle = () => {
    return onToggleFeaturedImage && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      className: "block-editor-media-placeholder__url-input-container",
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
        className: "block-editor-media-placeholder__button",
        onClick: onToggleFeaturedImage,
        variant: "secondary",
        children: (0, _i18n.__)('Use featured image')
      })
    });
  };
  const renderMediaUploadChecked = () => {
    const defaultButton = ({
      open
    }) => {
      return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
        variant: "secondary",
        onClick: () => {
          open();
        },
        children: (0, _i18n.__)('Media Library')
      });
    };
    const libraryButton = mediaLibraryButton !== null && mediaLibraryButton !== void 0 ? mediaLibraryButton : defaultButton;
    const uploadMediaLibraryButton = /*#__PURE__*/(0, _jsxRuntime.jsx)(_mediaUpload.default, {
      addToGallery: addToGallery,
      gallery: multiple && onlyAllowsImages(),
      multiple: multiple,
      onSelect: onSelect,
      allowedTypes: allowedTypes,
      mode: "browse",
      value: Array.isArray(value) ? value.map(({
        id
      }) => id) : value.id,
      render: libraryButton
    });
    if (mediaUpload && isAppender) {
      return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
        children: [renderDropZone(), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.FormFileUpload, {
          onChange: onUpload,
          accept: accept,
          multiple: !!multiple,
          render: ({
            openFileDialog
          }) => {
            const content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
              children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
                variant: "primary",
                className: (0, _clsx.default)('block-editor-media-placeholder__button', 'block-editor-media-placeholder__upload-button'),
                onClick: openFileDialog,
                children: (0, _i18n.__)('Upload')
              }), uploadMediaLibraryButton, renderUrlSelectionUI(), renderFeaturedImageToggle(), renderCancelLink()]
            });
            return renderPlaceholder(content);
          }
        })]
      });
    }
    if (mediaUpload) {
      const content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
        children: [renderDropZone(), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.FormFileUpload, {
          variant: "primary",
          className: (0, _clsx.default)('block-editor-media-placeholder__button', 'block-editor-media-placeholder__upload-button'),
          onChange: onUpload,
          accept: accept,
          multiple: !!multiple,
          children: (0, _i18n.__)('Upload')
        }), uploadMediaLibraryButton, renderUrlSelectionUI(), renderFeaturedImageToggle(), renderCancelLink()]
      });
      return renderPlaceholder(content);
    }
    return renderPlaceholder(uploadMediaLibraryButton);
  };
  if (disableMediaButtons) {
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(_check.default, {
      children: renderDropZone()
    });
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_check.default, {
    fallback: renderPlaceholder(renderUrlSelectionUI()),
    children: renderMediaUploadChecked()
  });
}

/**
 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-placeholder/README.md
 */
var _default = exports.default = (0, _components.withFilters)('editor.MediaPlaceholder')(MediaPlaceholder);
//# sourceMappingURL=index.js.map