"use strict";

exports.__esModule = true;
exports.default = Editor;

var _react = _interopRequireWildcard(require("react"));

var _styles = require("@mui/material/styles");

var _draftJs = require("draft-js");

var _draftjsToHtml = _interopRequireDefault(require("draftjs-to-html"));

var _reactIntl = require("react-intl");

var _RichTextEditor = _interopRequireDefault(require("./RichTextEditor"));

var _material = require("@mui/material");

var _core = require("@selfcommunity/core");

var _MediaChunkUploader = _interopRequireDefault(require("../../shared/MediaChunkUploader"));

var _chunkedUploady = _interopRequireDefault(require("@rpldy/chunked-uploady"));

var _uploadDropZone = _interopRequireDefault(require("@rpldy/upload-drop-zone"));

var _Icon = _interopRequireDefault(require("@mui/material/Icon"));

var _emojiPickerReact = _interopRequireDefault(require("emoji-picker-react"));

var _string = require("../../utils/string");

var _classnames = _interopRequireDefault(require("classnames"));

var _useThemeProps = _interopRequireDefault(require("@mui/material/styles/useThemeProps"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

const PREFIX = 'SCEditor';
const classes = {
  root: `${PREFIX}-root`,
  drop: `${PREFIX}-drop`,
  actions: `${PREFIX}-actions`
};
const Root = (0, _styles.styled)(_material.Box, {
  name: PREFIX,
  slot: 'Root',
  overridesResolver: (props, styles) => styles.root
})(({
  theme
}) => ({
  boxSizing: 'border-box',
  cursor: 'text',
  padding: theme.spacing(1),
  minHeight: 59,
  position: 'relative',
  [`& .${classes.drop}`]: {
    position: 'relative',
    '&::before': {
      content: 'attr(data-content)',
      position: 'absolute',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      backgroundColor: theme.palette.primary.main,
      color: theme.palette.primary.contrastText,
      zIndex: 2,
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center',
      alignItems: 'center'
    }
  },
  [`& .${classes.actions}`]: {
    position: 'absolute',
    bottom: 0,
    right: theme.spacing()
  }
}));
const messages = (0, _reactIntl.defineMessages)({
  placeholder: {
    id: 'ui.editor.placeholder',
    defaultMessage: 'ui.editor.placeholder'
  },
  drop: {
    id: 'ui.editor.drop',
    defaultMessage: 'ui.editor.drop'
  }
});

const User = props => {
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_material.ListItemAvatar, null, /*#__PURE__*/_react.default.createElement(_material.Avatar, {
    alt: props.username,
    src: props.avatar
  }, props.username.substr(0, 1))), /*#__PURE__*/_react.default.createElement(_material.ListItemText, {
    primary: props.username,
    secondary: props.realName
  }));
};

const EditorImage = props => {
  // Props
  const {
    blockProps
  } = props;
  const {
    src,
    width,
    height,
    rest
  } = blockProps; // Utils

  const calculateAspectRatioFit = (srcWidth, srcHeight, maxWidth, maxHeight) => {
    const ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
    return {
      width: srcWidth * ratio,
      height: srcHeight * ratio
    };
  };

  return /*#__PURE__*/_react.default.createElement("img", _extends({
    src: src
  }, calculateAspectRatioFit(width, height, 300, 300), rest));
};

/**
 * > API documentation for the Community-UI Editor component. Learn about the available props and the CSS API.

 #### Import

 ```jsx
 import {Editor} from '@selfcommunity/ui';
 ```

 #### Component Name

 The name `SCEditor` can be used when providing style overrides in the theme.

 #### CSS

 |Rule Name|Global class|Description|
 |---|---|---|
 |root|.SCEditor-root|Styles applied to the root element.|
 |drop|.SCEditor-drop|Styles applied to the drop element.|
 |actions|.SCEditor-actions|Styles applied to the actions section.|

 * @param inProps
 */
function Editor(inProps) {
  const editorId = (0, _react.useMemo)(() => `editor${(0, _string.random)()}`, []); // PROPS

  const props = (0, _useThemeProps.default)({
    props: inProps,
    name: PREFIX
  });
  const {
    id = 'editor',
    className = null,
    defaultValue = '',
    readOnly = false,
    onChange = null,
    onRef = null
  } = props; // Refs

  const editor = (0, _react.useRef)(null); // INTL

  const intl = (0, _reactIntl.useIntl)(); // Context

  const scContext = (0, _core.useSCContext)();
  const scUserContext = (0, _react.useContext)(_core.SCUserContext); // State

  const [uploading, setUploading] = (0, _react.useState)({});
  const [errors, setErrors] = (0, _react.useState)({});

  const [emojiAnchorEl, setEmojiAnchorEl] = _react.default.useState(null);
  /**
   * On mount if onRef in props
   * forward editor ref
   */


  (0, _react.useEffect)(() => {
    onRef && onRef(editor);
  }); // Default editor content

  const content = (0, _react.useMemo)(() => {
    const contentHTML = (0, _draftJs.convertFromHTML)(defaultValue);

    const state = _draftJs.ContentState.createFromBlockArray(contentHTML.contentBlocks, contentHTML.entityMap);

    return JSON.stringify((0, _draftJs.convertToRaw)(state));
  }, []); // UTILITY

  const searchMentions = async query => {
    const response = await _core.http.request({
      url: _core.Endpoints.UserSearch.url(),
      method: _core.Endpoints.UserSearch.method,
      params: {
        user: query,
        limit: 7
      }
    });
    return response.data.results.map(user => {
      return {
        keys: [user.email, user.username, user.real_name],
        value: `@${user.username}`,
        content: /*#__PURE__*/_react.default.createElement(User, {
          username: user.username,
          realName: user.real_name,
          avatar: user.avatar
        })
      };
    });
  }; // HANDLERS


  const handleUploadSuccess = media => {
    var _editor$current;

    const data = {
      src: media.image,
      width: media.image_width,
      height: media.image_height
    };
    (_editor$current = editor.current) == null ? void 0 : _editor$current.insertAtomicBlockSync('sc-image', data);
  };

  const handleUploadProgress = chunks => {
    setUploading(Object.assign({}, chunks));
  };

  const handleUploadError = (chunk, error) => {
    setErrors(Object.assign({}, errors, {
      [chunk.id]: Object.assign({}, chunk, {
        error
      })
    }));
  };

  const handleRemoveUploadErrors = id => {
    return () => {
      delete errors[id];
      setErrors(Object.assign({}, errors));
    };
  };

  const handleChange = editor => {
    onChange && onChange((0, _draftjsToHtml.default)((0, _draftJs.convertToRaw)(editor.getCurrentContent())));
  };

  const handleFileUploadFilter = (file, index, a) => {
    return file.type.startsWith('image/');
  };

  const handleToggleEmoji = event => {
    setEmojiAnchorEl(emojiAnchorEl ? null : event.currentTarget);
  };

  const handleEmojiClick = (event, emoji) => {
    var _editor$current2;

    (_editor$current2 = editor.current) == null ? void 0 : _editor$current2.insertText(emoji.emoji);
  };

  return /*#__PURE__*/_react.default.createElement(Root, {
    id: id,
    className: (0, _classnames.default)(classes.root, className)
  }, scUserContext.user && /*#__PURE__*/_react.default.createElement(_chunkedUploady.default, {
    destination: {
      url: `${scContext.settings.portal}${_core.Endpoints.ComposerChunkUploadMedia.url()}`,
      headers: Object.assign({}, scContext.settings.session && scContext.settings.session.authToken && {
        Authorization: `Bearer ${scContext.settings.session.authToken.accessToken}`
      }),
      method: _core.Endpoints.ComposerChunkUploadMedia.method
    },
    chunkSize: 2142880,
    multiple: true,
    accept: "image/*",
    fileFilter: handleFileUploadFilter
  }, /*#__PURE__*/_react.default.createElement(_MediaChunkUploader.default, {
    type: "eimage",
    onSuccess: handleUploadSuccess,
    onProgress: handleUploadProgress,
    onError: handleUploadError
  }), /*#__PURE__*/_react.default.createElement(_uploadDropZone.default, {
    onDragOverClassName: classes.drop,
    inputFieldName: "image",
    extraProps: {
      'data-content': intl.formatMessage(messages.drop)
    }
  }, /*#__PURE__*/_react.default.createElement(_RichTextEditor.default, {
    id: editorId,
    readOnly: readOnly,
    label: intl.formatMessage(messages.placeholder),
    onChange: handleChange,
    ref: editor,
    defaultValue: content,
    inlineToolbarControls: ['bold', 'italic', 'underline', 'strikethrough', 'highlight', 'link', 'clear'],
    customControls: [{
      name: 'sc-image',
      type: 'atomic',
      atomicComponent: EditorImage
    }],
    toolbar: false,
    inlineToolbar: true,
    autocomplete: {
      strategies: [{
        asyncItems: searchMentions,
        triggerChar: '@'
      }]
    }
  }), (uploading || errors) && /*#__PURE__*/_react.default.createElement(_material.Stack, null, Object.values(uploading).map(chunk => /*#__PURE__*/_react.default.createElement(_material.Fade, {
    in: true,
    key: chunk.id
  }, /*#__PURE__*/_react.default.createElement(_material.Box, null, chunk.name, /*#__PURE__*/_react.default.createElement(_material.LinearProgress, {
    variant: "determinate",
    value: chunk.completed
  })))), Object.keys(errors).map(id => /*#__PURE__*/_react.default.createElement(_material.Fade, {
    in: true,
    key: id
  }, /*#__PURE__*/_react.default.createElement(_material.Alert, {
    severity: "error",
    onClose: handleRemoveUploadErrors(id)
  }, /*#__PURE__*/_react.default.createElement(_material.AlertTitle, null, errors[id].name), errors[id].error)))))), /*#__PURE__*/_react.default.createElement(_material.Stack, {
    className: classes.actions
  }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_material.IconButton, {
    size: "small",
    onClick: handleToggleEmoji
  }, /*#__PURE__*/_react.default.createElement(_Icon.default, null, "sentiment_satisfied_alt")), /*#__PURE__*/_react.default.createElement(_material.Popover, {
    open: Boolean(emojiAnchorEl),
    anchorEl: emojiAnchorEl,
    onClose: handleToggleEmoji,
    anchorOrigin: {
      vertical: 'top',
      horizontal: 'right'
    },
    transformOrigin: {
      vertical: 'bottom',
      horizontal: 'left'
    },
    sx: theme => {
      return {
        zIndex: theme.zIndex.tooltip
      };
    }
  }, /*#__PURE__*/_react.default.createElement(_emojiPickerReact.default, {
    onEmojiClick: handleEmojiClick
  })))));
}