import React from 'react'; import PropTypes from 'prop-types'; import path from 'path'; import { Modal, ModalHeader, ModalBody, ModalFooter, } from 'reactstrap'; 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: '', isEnablePermanentLink: false, }; 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.handleChangeLinkInput = this.handleChangeLinkInput.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.getPageWithLinkInputValue = this.getPageWithLinkInputValue.bind(this); this.renderPreview = this.renderPreview.bind(this); } componentDidUpdate(prevState) { const { linkInputValue: prevLinkInputValue } = prevState; const { linkInputValue } = this.state; if (linkInputValue !== prevLinkInputValue) { this.getPageWithLinkInputValue(linkInputValue); } } // defaultMarkdownLink is an instance of Linker show(defaultMarkdownLink = null) { // if defaultMarkdownLink is null, set default value in inputs. const { label = '', link = '' } = defaultMarkdownLink; let { 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; } this.setState({ show: true, labelInputValue: label, linkInputValue: link, linkerType: type, }); } cancel() { this.hide(); } hide() { this.setState({ show: false, }); } toggleIsUseRelativePath() { if (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.isEnablePermanentLink) { return; } // User can't use both relativePath and permalink at the same time this.setState({ isUsePermanentLink: !this.state.isUsePermanentLink, isUseRelativePath: false }); } renderPreview() { return (
); } async setMarkdown(path) { let markdown = ''; try { await this.props.appContainer.apiGet('/pages.get', { path }).then((res) => { markdown = res.page.revision.body; }); } catch (err) { markdown = ``; } this.setState({ markdown }); } handleChangeLabelInput(label) { this.setState({ labelInputValue: label }); } handleChangeLinkInput(link) { this.setState({ linkInputValue: link }); } handleSelecteLinkerType(linkerType) { if (this.state.isUseRelativePath && linkerType === Linker.types.growiLink) { this.toggleIsUseRelativePath(); } this.setState({ linkerType }); } save() { const output = this.generateLink(); if (this.props.onSave != null) { this.props.onSave(output); } this.hide(); } async getPageWithLinkInputValue(path) { let markdown = ''; let permalink = ''; let isEnablePermanentLink = false; try { const res = await this.props.appContainer.apiGet('/pages.get', { path }); markdown = res.page.revision.body; permalink = `${window.location.origin}/${res.page.id}`; isEnablePermanentLink = true; } catch (err) { markdown = ``; } this.setState({ markdown, permalink, isEnablePermanentLink }); } generateLink() { const { pageContainer } = this.props; const { linkInputValue, labelInputValue, linkerType, isUseRelativePath, isUsePermanentLink, } = this.state; let reshapedLink = linkInputValue; if (isUseRelativePath && linkInputValue.match(/^\//)) { reshapedLink = path.relative(pageContainer.state.path, linkInputValue); } if (isUsePermanentLink) { reshapedLink = this.state.permalink; } if (linkerType === Linker.types.pukiwikiLink) { return `[[${labelInputValue}>${reshapedLink}]]`; } if (linkerType === Linker.types.growiLink) { return `[${reshapedLink}]`; } if (linkerType === Linker.types.markdownLink) { return `[${labelInputValue}](${reshapedLink})`; } } render() { return ( Edit Links
{this.renderPreview()}
{this.isApplyPukiwikiLikeLinkerPlugin && ( )}
this.handleChangeLabelInput(e.target.value)} disabled={this.state.linkerType === Linker.types.growiLink} />
{this.renderPreview()}
); } } LinkEditModal.propTypes = { appContainer: PropTypes.instanceOf(AppContainer).isRequired, pageContainer: PropTypes.instanceOf(PageContainer).isRequired, onSave: PropTypes.func, }; /** * Wrapper component for using unstated */ const LinkEditModalWrapper = withUnstatedContainers(LinkEditModal, [AppContainer, PageContainer]); export default LinkEditModalWrapper;