import React from 'react'; import PropTypes from 'prop-types'; import { Modal, ModalHeader, ModalBody, ModalFooter, } from 'reactstrap'; import { debounce } from 'throttle-debounce'; import path from 'path'; import Preview from './Preview'; import AppContainer from '../../services/AppContainer'; import PageContainer from '../../services/PageContainer'; import SearchTypeahead from '../SearchTypeahead'; import Linker from '../../models/Linker'; import { withUnstatedContainers } from '../UnstatedUtils'; class LinkEditModal extends React.PureComponent { constructor(props) { super(props); this.state = { show: false, isUseRelativePath: false, isUsePermanentLink: false, linkInputValue: '', labelInputValue: '', linkerType: Linker.types.markdownLink, markdown: '', permalink: '', }; this.isApplyPukiwikiLikeLinkerPlugin = window.growiRenderer.preProcessors.some(process => process.constructor.name === 'PukiwikiLikeLinker'); this.show = this.show.bind(this); this.hide = this.hide.bind(this); this.cancel = this.cancel.bind(this); this.handleChangeTypeahead = this.handleChangeTypeahead.bind(this); this.handleChangeLabelInput = this.handleChangeLabelInput.bind(this); this.handleChangeLinkInput = this.handleChangeLinkInput.bind(this); this.handleSelecteLinkerType = this.handleSelecteLinkerType.bind(this); this.toggleIsUseRelativePath = this.toggleIsUseRelativePath.bind(this); this.toggleIsUsePamanentLink = this.toggleIsUsePamanentLink.bind(this); this.save = this.save.bind(this); this.generateLink = this.generateLink.bind(this); this.renderPreview = this.renderPreview.bind(this); this.getRootPath = this.getRootPath.bind(this); this.getPreviewDebounced = debounce(200, this.getPreview.bind(this)); } componentDidUpdate(prevState) { const { linkInputValue: prevLinkInputValue } = prevState; const { linkInputValue } = this.state; if (linkInputValue !== prevLinkInputValue) { this.getPreviewDebounced(linkInputValue); } } // defaultMarkdownLink is an instance of Linker show(defaultMarkdownLink = null) { // if defaultMarkdownLink is null, set default value in inputs. const { label = '' } = defaultMarkdownLink; let { link = '', type = Linker.types.markdownLink } = defaultMarkdownLink; // if type of defaultMarkdownLink is pukiwikiLink when pukiwikiLikeLinker plugin is disable, change type(not change label and link) if (type === Linker.types.pukiwikiLink && !this.isApplyPukiwikiLikeLinkerPlugin) { type = Linker.types.markdownLink; } const url = new URL(link, 'http://example.com'); const isUseRelativePath = url.origin === 'http://example.com' && !link.startsWith('/') && link !== ''; if (isUseRelativePath) { const rootPath = this.getRootPath(type); link = path.resolve(rootPath, link); } this.setState({ show: true, labelInputValue: label, linkInputValue: link, isUsePermanentLink: false, permalink: '', linkerType: type, isUseRelativePath, }); } cancel() { this.hide(); } hide() { this.setState({ show: false, }); } toggleIsUseRelativePath() { if (!this.state.linkInputValue.startsWith('/') || this.state.linkerType === Linker.types.growiLink) { return; } // User can't use both relativePath and permalink at the same time this.setState({ isUseRelativePath: !this.state.isUseRelativePath, isUsePermanentLink: false }); } toggleIsUsePamanentLink() { if (this.state.permalink === '' || this.state.linkerType === Linker.types.growiLink) { return; } // User can't use both relativePath and permalink at the same time this.setState({ isUsePermanentLink: !this.state.isUsePermanentLink, isUseRelativePath: false }); } renderPreview() { return (