diff --git a/app/soapbox/components/status.js b/app/soapbox/components/status.js index 1ff0b1e03..7b0d328df 100644 --- a/app/soapbox/components/status.js +++ b/app/soapbox/components/status.js @@ -94,6 +94,7 @@ class Status extends ImmutablePureComponent { group: ImmutablePropTypes.map, displayMedia: PropTypes.string, allowedEmoji: ImmutablePropTypes.list, + greentext: PropTypes.bool, }; // Avoid checking props that are functions (and whose equality will always @@ -494,6 +495,7 @@ class Status extends ImmutablePureComponent { onClick={this.handleClick} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} + greentext={this.props.greentext} collapsable /> diff --git a/app/soapbox/components/status_content.js b/app/soapbox/components/status_content.js index d1b829d18..d539a31f7 100644 --- a/app/soapbox/components/status_content.js +++ b/app/soapbox/components/status_content.js @@ -22,6 +22,7 @@ export default class StatusContent extends React.PureComponent { onExpandedToggle: PropTypes.func, onClick: PropTypes.func, collapsable: PropTypes.bool, + greentext: PropTypes.bool, }; state = { @@ -153,7 +154,28 @@ export default class StatusContent extends React.PureComponent { const properContent = status.get('contentHtml'); - return properContent; + return this.greentext(properContent); + } + + greentext = string => { + if (!this.props.greentext) return string; + + // Copied from Pleroma FE + // https://git.pleroma.social/pleroma/pleroma-fe/-/blob/19475ba356c3fd6c54ca0306d3ae392358c212d1/src/components/status_content/status_content.js#L132 + try { + if (string.includes('>') && + string + .replace(/<[^>]+?>/gi, '') // remove all tags + .replace(/@\w+/gi, '') // remove mentions (even failed ones) + .trim() + .startsWith('>')) { + return `${string}`; + } else { + return string; + } + } catch(e) { + return string; + } } render() { diff --git a/app/soapbox/containers/status_container.js b/app/soapbox/containers/status_container.js index 2f4e63287..b4c2fbfcf 100644 --- a/app/soapbox/containers/status_container.js +++ b/app/soapbox/containers/status_container.js @@ -52,11 +52,16 @@ const messages = defineMessages({ const makeMapStateToProps = () => { const getStatus = makeGetStatus(); - const mapStateToProps = (state, props) => ({ - status: getStatus(state, props), - displayMedia: getSettings(state).get('displayMedia'), - allowedEmoji: getSoapboxConfig(state).get('allowedEmoji'), - }); + const mapStateToProps = (state, props) => { + const soapbox = getSoapboxConfig(state); + + return { + status: getStatus(state, props), + displayMedia: getSettings(state).get('displayMedia'), + allowedEmoji: soapbox.get('allowedEmoji'), + greentext: soapbox.get('greentext'), + }; + }; return mapStateToProps; }; diff --git a/app/soapbox/features/soapbox_config/index.js b/app/soapbox/features/soapbox_config/index.js index dfcfffc32..3443d7279 100644 --- a/app/soapbox/features/soapbox_config/index.js +++ b/app/soapbox/features/soapbox_config/index.js @@ -49,6 +49,7 @@ const messages = defineMessages({ rawJSONHint: { id: 'soapbox_config.raw_json_hint', defaultMessage: 'Edit the settings data directly. Changes made directly to the JSON file will override the form fields above. Click "Save" to apply your changes.' }, verifiedCanEditNameLabel: { id: 'soapbox_config.verified_can_edit_name_label', defaultMessage: 'Allow verified users to edit their own display name.' }, displayFqnLabel: { id: 'soapbox_config.display_fqn_label', defaultMessage: 'Display domain (eg @user@domain) for local accounts.' }, + greentextLabel: { id: 'soapbox_config.greentext_label', defaultMessage: 'Enable greentext support' }, }); const listenerOptions = supportsPassiveEvents ? { passive: true } : false; @@ -258,11 +259,17 @@ class SoapboxConfig extends ImmutablePureComponent { onChange={this.handleChange(['verifiedCanEditName'], (e) => e.target.checked)} /> e.target.checked)} /> + e.target.checked)} + />
diff --git a/app/soapbox/features/status/components/detailed_status.js b/app/soapbox/features/status/components/detailed_status.js index c26a634b1..e5ade55b8 100644 --- a/app/soapbox/features/status/components/detailed_status.js +++ b/app/soapbox/features/status/components/detailed_status.js @@ -36,6 +36,7 @@ export default class DetailedStatus extends ImmutablePureComponent { compact: PropTypes.bool, showMedia: PropTypes.bool, onToggleMediaVisibility: PropTypes.func, + greentext: PropTypes.bool, }; state = { @@ -188,7 +189,12 @@ export default class DetailedStatus extends ImmutablePureComponent {
)} - + {media} {poll} diff --git a/app/soapbox/features/status/containers/detailed_status_container.js b/app/soapbox/features/status/containers/detailed_status_container.js index 668ba020f..f47781ee2 100644 --- a/app/soapbox/features/status/containers/detailed_status_container.js +++ b/app/soapbox/features/status/containers/detailed_status_container.js @@ -31,6 +31,7 @@ import { openModal } from '../../../actions/modal'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { showAlertForError } from '../../../actions/alerts'; import { getSettings } from 'soapbox/actions/settings'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; import { deactivateUserModal, deleteUserModal, deleteStatusModal, toggleStatusSensitivityModal } from 'soapbox/actions/moderation'; const messages = defineMessages({ @@ -50,6 +51,7 @@ const makeMapStateToProps = () => { const mapStateToProps = (state, props) => ({ status: getStatus(state, props), domain: state.getIn(['meta', 'domain']), + greentext: getSoapboxConfig(state).get('greentext'), }); return mapStateToProps; diff --git a/app/soapbox/features/status/index.js b/app/soapbox/features/status/index.js index be0c31b03..bff909f8f 100644 --- a/app/soapbox/features/status/index.js +++ b/app/soapbox/features/status/index.js @@ -105,6 +105,8 @@ const makeMapStateToProps = () => { }); } + const soapbox = getSoapboxConfig(state); + return { status, ancestorsIds, @@ -113,7 +115,8 @@ const makeMapStateToProps = () => { domain: state.getIn(['meta', 'domain']), me: state.get('me'), displayMedia: getSettings(state).get('displayMedia'), - allowedEmoji: getSoapboxConfig(state).get('allowedEmoji'), + allowedEmoji: soapbox.get('allowedEmoji'), + greentext: soapbox.get('greentext'), }; }; @@ -543,6 +546,7 @@ class Status extends ImmutablePureComponent { onToggleHidden={this.handleToggleHidden} domain={domain} showMedia={this.state.showMedia} + greentext={this.props.greentext} onToggleMediaVisibility={this.handleToggleMediaVisibility} /> diff --git a/app/styles/basics.scss b/app/styles/basics.scss index 964862aec..0406524c4 100644 --- a/app/styles/basics.scss +++ b/app/styles/basics.scss @@ -199,3 +199,7 @@ noscript { margin: 0; padding: 0; } + +.greentext { + color: #789922; +}