diff --git a/app/javascript/gabsocial/actions/compose.js b/app/javascript/gabsocial/actions/compose.js index 9745469f..642ebd4b 100644 --- a/app/javascript/gabsocial/actions/compose.js +++ b/app/javascript/gabsocial/actions/compose.js @@ -264,30 +264,22 @@ export function submitCompose(group, replyToId = null, router, isStandalone) { let status = getState().getIn(['compose', 'text'], ''); let markdown = getState().getIn(['compose', 'markdown'], ''); - const media = getState().getIn(['compose', 'media_attachments']); + const media = getState().getIn(['compose', 'media_attachments']); - // : hack : - //Prepend http:// to urls in status that don't have protocol - status = `${status}`.replace(urlRegex, (match, a, b, c) =>{ + const replacer = (match) => { const hasProtocol = match.startsWith('https://') || match.startsWith('http://') //Make sure not a remote mention like @someone@somewhere.com if (!hasProtocol) { if (status.indexOf(`@${match}`) > -1) return match } return hasProtocol ? match : `http://${match}` - }) - markdown = !!markdown ? markdown.replace(urlRegex, (match) =>{ - const hasProtocol = match.startsWith('https://') || match.startsWith('http://') - if (!hasProtocol) { - if (status.indexOf(`@${match}`) > -1) return match - } - return hasProtocol ? match : `http://${match}` - }) : undefined - - if (status === markdown) { - markdown = undefined } + // : hack : + //Prepend http:// to urls in status that don't have protocol + status = `${status}`.replace(urlRegex, replacer) + markdown = !!markdown ? `${markdown}`.replace(urlRegex, replacer) : undefined + const inReplyToId = getState().getIn(['compose', 'in_reply_to'], null) || replyToId dispatch(submitComposeRequest()); diff --git a/app/javascript/gabsocial/components/autosuggest_textbox.js b/app/javascript/gabsocial/components/autosuggest_textbox.js index c2f88c79..6a32159e 100644 --- a/app/javascript/gabsocial/components/autosuggest_textbox.js +++ b/app/javascript/gabsocial/components/autosuggest_textbox.js @@ -36,6 +36,8 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { onBlur: PropTypes.func, textarea: PropTypes.bool, small: PropTypes.bool, + isPro: PropTypes.bool, + isEdit: PropTypes.bool, } static defaultProps = { @@ -211,6 +213,8 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { children, valueMarkdown, id, + isPro, + isEdit, } = this.props const { suggestionsHidden } = this.state @@ -284,6 +288,8 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { onBlur={this.onBlur} onPaste={this.onPaste} small={small} + isEdit={isEdit} + isPro={isPro} /> diff --git a/app/javascript/gabsocial/components/composer.js b/app/javascript/gabsocial/components/composer.js index 38e14dac..9de67775 100644 --- a/app/javascript/gabsocial/components/composer.js +++ b/app/javascript/gabsocial/components/composer.js @@ -18,6 +18,21 @@ import '!style-loader!css-loader!draft-js/dist/Draft.css' const cx = classNames.bind(_s) +const markdownOptions = { + escapeMarkdownCharacters: false, + preserveNewlines: true, + remarkablePreset: 'commonmark', + remarkableOptions: { + disable: { + inline: ['links'], + block: ['table', 'heading'], + }, + enable: { + inline: ['del', 'ins'], + } + } +} + const getBlockStyle = (block) => { switch (block.getType()) { case 'blockquote': @@ -100,6 +115,8 @@ export default class Composer extends PureComponent { onBlur: PropTypes.func, onPaste: PropTypes.func, small: PropTypes.bool, + isPro: PropTypes.bool, + isEdit: PropTypes.bool, } state = { @@ -109,8 +126,8 @@ export default class Composer extends PureComponent { } componentDidMount() { - if (this.props.valueMarkdown) { - const rawData = markdownToDraft(this.props.valueMarkdown) + if (this.props.valueMarkdown && this.props.isPro && this.props.isEdit) { + const rawData = markdownToDraft(this.props.valueMarkdown, markdownOptions) const contentState = convertFromRaw(rawData) const editorState = EditorState.createWithContent(contentState) @@ -146,29 +163,23 @@ export default class Composer extends PureComponent { onChange = (editorState) => { const content = editorState.getCurrentContent() - const plainText = content.getPlainText('\u0001') + // const plainText = content.getPlainText('\u0001') - this.setState({ editorState, plainText }) + const blocks = convertToRaw(editorState.getCurrentContent()).blocks + const value = blocks.map(block => (!block.text.trim() && '') || block.text).join('\n') + + this.setState({ + editorState, + plainText: value, + }) const selectionState = editorState.getSelection() const selectionStart = selectionState.getStartOffset() const rawObject = convertToRaw(content) - const markdownString = draftToMarkdown(rawObject, { - escapeMarkdownCharacters: false, - preserveNewlines: false, - remarkablePreset: 'commonmark', - remarkableOptions: { - disable: { - block: ['table'] - }, - enable: { - inline: ['del', 'ins'], - } - } - }) + const markdownString = this.props.isPro ? draftToMarkdown(rawObject,markdownOptions) : null - this.props.onChange(null, plainText, markdownString, selectionStart) + this.props.onChange(null, value, markdownString, selectionStart) } handleOnFocus = () => { @@ -227,6 +238,7 @@ export default class Composer extends PureComponent { disabled, placeholder, small, + isPro, } = this.props const { editorState } = this.state @@ -247,7 +259,7 @@ export default class Composer extends PureComponent {
{ - !small && + !small && isPro && @@ -414,6 +418,8 @@ class ComposeForm extends ImmutablePureComponent { onPaste={onPaste} autoFocus={shouldAutoFocus} small={shouldCondense} + isPro={isPro} + isEdit={!!edit} id='main-composer' /> diff --git a/app/javascript/gabsocial/features/compose/containers/compose_form_container.js b/app/javascript/gabsocial/features/compose/containers/compose_form_container.js index 2e232bae..ba216bb6 100644 --- a/app/javascript/gabsocial/features/compose/containers/compose_form_container.js +++ b/app/javascript/gabsocial/features/compose/containers/compose_form_container.js @@ -90,12 +90,13 @@ const mapStateToProps = (state, props) => { quoteOfId: state.getIn(['compose', 'quote_of_id']), scheduledAt: state.getIn(['compose', 'scheduled_at']), account: state.getIn(['accounts', me]), + isPro: state.getIn(['accounts', me, 'is_pro']), hasPoll: state.getIn(['compose', 'poll']), selectedGifSrc: state.getIn(['tenor', 'selectedGif', 'src']), } } -const mapDispatchToProps = (dispatch, { reduxReplyToId, replyToId, isStandalone }) => ({ +const mapDispatchToProps = (dispatch, { isStandalone }) => ({ onChange(text, markdown, newReplyToId, position) { dispatch(changeCompose(text, markdown, newReplyToId, isStandalone, position)) diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 22818ca8..deb945fb 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -123,7 +123,8 @@ class Formatter def format_markdown(html) html = markdown_formatter.render(html) - html.delete("\r").delete("\n") + # html.delete("\r").delete("\n") + html = html.gsub(/(?:\n\r?|\r\n?)/, '
') end def reformat(html, outgoing = false)