diff --git a/Gemfile b/Gemfile index ec339981..387d5508 100644 --- a/Gemfile +++ b/Gemfile @@ -94,6 +94,8 @@ gem 'json-ld', '~> 3.0' gem 'json-ld-preloaded', '~> 3.0' gem 'rdf-normalize', '~> 0.3' +gem 'redcarpet', '~> 3.4' + group :development, :test do gem 'fabrication', '~> 2.20' gem 'fuubar', '~> 2.3' diff --git a/Gemfile.lock b/Gemfile.lock index e64ff643..5d095708 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -479,6 +479,7 @@ GEM link_header (~> 0.0, >= 0.0.8) rdf-normalize (0.3.3) rdf (>= 2.2, < 4.0) + redcarpet (3.4.0) redis (4.1.2) redis-actionpack (5.0.2) actionpack (>= 4.0, < 6) @@ -740,6 +741,7 @@ DEPENDENCIES rails-i18n (~> 5.1) rails-settings-cached (~> 0.6) rdf-normalize (~> 0.3) + redcarpet (~> 3.4) redis (~> 4.1) redis-namespace (~> 1.5) redis-rails (~> 5.0) diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index e800bff4..cdee103e 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -52,9 +52,10 @@ class Api::V1::StatusesController < Api::BaseController end def create + markdown = status_params[:markdown] unless status_params[:markdown] === status_params[:status] @status = PostStatusService.new.call(current_user.account, text: status_params[:status], - markdown: status_params[:markdown], + markdown: markdown, thread: status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]), media_ids: status_params[:media_ids], sensitive: status_params[:sensitive], @@ -72,9 +73,10 @@ class Api::V1::StatusesController < Api::BaseController def update authorize @status, :update? - + markdown = status_params[:markdown] unless status_params[:markdown] === status_params[:status] @status = EditStatusService.new.call(@status, text: status_params[:status], + markdown: markdown, media_ids: status_params[:media_ids], sensitive: status_params[:sensitive], spoiler_text: status_params[:spoiler_text], diff --git a/app/javascript/gabsocial/actions/compose.js b/app/javascript/gabsocial/actions/compose.js index f476da49..9745469f 100644 --- a/app/javascript/gabsocial/actions/compose.js +++ b/app/javascript/gabsocial/actions/compose.js @@ -263,12 +263,12 @@ export function submitCompose(group, replyToId = null, router, isStandalone) { if (!me) return; let status = getState().getIn(['compose', 'text'], ''); - const markdown = getState().getIn(['compose', 'markdown'], ''); + let markdown = getState().getIn(['compose', 'markdown'], ''); 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) =>{ + status = `${status}`.replace(urlRegex, (match, a, b, c) =>{ const hasProtocol = match.startsWith('https://') || match.startsWith('http://') //Make sure not a remote mention like @someone@somewhere.com if (!hasProtocol) { @@ -276,15 +276,20 @@ export function submitCompose(group, replyToId = null, router, isStandalone) { } return hasProtocol ? match : `http://${match}` }) - // markdown = statusMarkdown.replace(urlRegex, (match) =>{ - // const hasProtocol = match.startsWith('https://') || match.startsWith('http://') - // 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 + } const inReplyToId = getState().getIn(['compose', 'in_reply_to'], null) || replyToId - // console.log("markdown:", markdown) - dispatch(submitComposeRequest()); dispatch(closeModal()); @@ -706,9 +711,9 @@ export function changeScheduledAt(date) { }; }; -export function changeRichTextEditorControlsVisibility(status) { +export function changeRichTextEditorControlsVisibility(open) { return { type: COMPOSE_RICH_TEXT_EDITOR_CONTROLS_VISIBILITY, - status: status, + open, } } \ No newline at end of file diff --git a/app/javascript/gabsocial/actions/importer/normalizer.js b/app/javascript/gabsocial/actions/importer/normalizer.js index eaa4ca17..1de5700f 100644 --- a/app/javascript/gabsocial/actions/importer/normalizer.js +++ b/app/javascript/gabsocial/actions/importer/normalizer.js @@ -1,9 +1,9 @@ -import escapeTextContentForBrowser from 'escape-html'; -import emojify from '../../components/emoji/emoji'; -import { unescapeHTML } from '../../utils/html'; -import { expandSpoilers } from '../../initial_state'; +import escapeTextContentForBrowser from 'escape-html' +import emojify from '../../components/emoji/emoji' +import { unescapeHTML } from '../../utils/html' +import { expandSpoilers } from '../../initial_state' -const domParser = new DOMParser(); +const domParser = new DOMParser() const makeEmojiMap = record => record.emojis.reduce((obj, emoji) => { obj[`:${emoji.shortcode}:`] = emoji; @@ -86,3 +86,21 @@ export function normalizePoll(poll) { return normalPoll; } + + +//

attention!

+//

#test @bob #nice https://bob.com http://techcrunch.com strike it

+//

https://twitter.com

+//

@bobitalic

+//

jonincode

+ +// # attention! +// #test @bob #nice https://bob.com http://techcrunch.com ~~strike it~~ + +// ~~https://twitter.com~~ + +// _@bobitalic_ + +// ``` +// jonincode +// ``` \ No newline at end of file diff --git a/app/javascript/gabsocial/components/autosuggest_textbox.js b/app/javascript/gabsocial/components/autosuggest_textbox.js index 0576c7d1..f4aff23f 100644 --- a/app/javascript/gabsocial/components/autosuggest_textbox.js +++ b/app/javascript/gabsocial/components/autosuggest_textbox.js @@ -15,6 +15,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { static propTypes = { value: PropTypes.string, + valueMarkdown: PropTypes.string, suggestions: ImmutablePropTypes.list, disabled: PropTypes.bool, placeholder: PropTypes.string, @@ -45,11 +46,12 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { tokenStart: 0, } - onChange = (e, value, selectionStart, markdown) => { + onChange = (e, value, markdown, selectionStart) => { if (!isObject(e)) { e = { target: { value, + markdown, selectionStart, }, } @@ -65,7 +67,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { this.props.onSuggestionsClearRequested(); } - this.props.onChange(e, markdown); + this.props.onChange(e); } onKeyDown = (e) => { @@ -191,7 +193,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { } setTextbox = (c) => { - this.textbox = c; + this.textbox = c } render() { @@ -203,6 +205,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { placeholder, onKeyUp, children, + valueMarkdown, id, } = this.props @@ -246,29 +249,14 @@ export default class AutosuggestTextbox extends ImmutablePureComponent { -