import React from 'react'; import marked from 'marked'; import { get } from 'lodash'; import axios from '../../axios/axios'; import { ContentContainer } from '../content-container/content-container'; import { ReplyModel } from '../../model'; import './editor.scss'; interface Props { categoryId?: number; onClose: (cancel: boolean) => any; editingReply?: ReplyModel; quotedReply?: ReplyModel; threadId?: string; } interface State { title: string; content: string; contentPreview: string; contentCharacterCount: number; errorMessage?: string; } export class Editor extends React.Component { private titleRef: any; private contentRef: any; constructor(props: any) { super(props); this.state = { title: '', content: '', contentPreview: '', contentCharacterCount: 0, }; } // disable scrolling in the background componentDidMount() { document.body.style.overflow = 'hidden'; // set content if user is editing a reply if (this.props.editingReply) { this.onContentChange({ target: { value: this.props.editingReply.content } }); } if (this.titleRef) { this.titleRef.focus(); } else { this.contentRef.focus(); } } componentWillUnmount() { document.body.style.removeProperty('overflow'); } onContentChange(event: any) { this.setState({ content: event.target.value, contentPreview: marked(event.target.value, { sanitize: true }), contentCharacterCount: event.target.value.length, }); } onTitleChange(event: any) { this.setState({ title: event.target.value, }); } onSubmit(event: any) { event.preventDefault(); if (this.props.threadId) { this.newReply(); } else { this.newThread(); } } getErrorMessage(e: any) { return get(e, 'response.status') === 429 ? 'You are doing that too much! Please try again in a few minutes.' : 'Server error. Please try again later.'; } async newReply() { const { content } = this.state; if (content === '') { this.setState({ errorMessage: 'Content must not be blank.' }); return; } const data = { content, id: get(this.props, 'editingReply.id'), thread_id: this.props.threadId, quote_id: get(this.props, 'quotedReply.id') || undefined, }; try { this.props.editingReply ? await axios.put('/api/reply', data) : await axios.post('/api/reply', data); this.props.onClose(false); } catch (e) { this.setState({ errorMessage: this.getErrorMessage(e) }); } } async newThread() { const { title, content } = this.state; if (title === '' || content === '') { this.setState({ errorMessage: 'One of your inputs is blank.' }); return; } const data = { content, title, category_id: this.props.categoryId, }; try { await axios.post('/api/thread', data); this.props.onClose(false); } catch (e) { this.setState({ errorMessage: this.getErrorMessage(e) }); } } private renderTopicInput(): any { return (
this.titleRef = ref} className="input editor__title" onChange={event => this.onTitleChange(event)} maxLength={300}/>
); } renderQuotedReply() { return (this.props.quotedReply &&
Q u o t e:
); } getEditorTitle(): string { if (!this.props.threadId) { return 'New Topic'; } return `${this.props.editingReply ? 'Edit' : 'New'} Reply`; } render() { return (
this.onSubmit(event)} onReset={() => this.props.onClose(true)}>

{this.getEditorTitle()}

{!this.props.threadId && this.renderTopicInput()}