diff --git a/app/soapbox/features/compose/components/compose_form.js b/app/soapbox/features/compose/components/compose_form.js index 64a8910f9..d6a743122 100644 --- a/app/soapbox/features/compose/components/compose_form.js +++ b/app/soapbox/features/compose/components/compose_form.js @@ -83,6 +83,7 @@ export default class ComposeForm extends ImmutablePureComponent { isModalOpen: PropTypes.bool, clickableAreaRef: PropTypes.object, scheduledAt: PropTypes.instanceOf(Date), + features: PropTypes.object.isRequired, }; static defaultProps = { @@ -254,7 +255,7 @@ export default class ComposeForm extends ImmutablePureComponent { } render() { - const { intl, onPaste, showSearch, anyMedia, shouldCondense, autoFocus, isModalOpen, maxTootChars, scheduledStatusCount } = this.props; + const { intl, onPaste, showSearch, anyMedia, shouldCondense, autoFocus, isModalOpen, maxTootChars, scheduledStatusCount, features } = this.props; const condensed = shouldCondense && !this.state.composeFocused && this.isEmpty() && !this.props.isUploading; const disabled = this.props.isSubmitting; const text = [this.props.spoilerText, countableText(this.props.text)].join(''); @@ -366,12 +367,12 @@ export default class ComposeForm extends ImmutablePureComponent {
- - - - - - + {features.media && } + {features.polls && } + {features.privacyScopes && } + {features.scheduledStatuses && } + {features.spoilers && } + {features.richText && }
{maxTootChars && (
diff --git a/app/soapbox/features/compose/components/markdown_button.js b/app/soapbox/features/compose/components/markdown_button.js index d03217ee0..202bc0cf7 100644 --- a/app/soapbox/features/compose/components/markdown_button.js +++ b/app/soapbox/features/compose/components/markdown_button.js @@ -17,7 +17,6 @@ class MarkdownButton extends React.PureComponent { active: PropTypes.bool, onClick: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, - unavailable: PropTypes.bool, }; handleClick = () => { @@ -25,11 +24,7 @@ class MarkdownButton extends React.PureComponent { } render() { - const { intl, active, unavailable } = this.props; - - if (unavailable) { - return null; - } + const { intl, active } = this.props; return (
diff --git a/app/soapbox/features/compose/containers/compose_form_container.js b/app/soapbox/features/compose/containers/compose_form_container.js index bf34ad39e..40fd56d14 100644 --- a/app/soapbox/features/compose/containers/compose_form_container.js +++ b/app/soapbox/features/compose/containers/compose_form_container.js @@ -1,6 +1,8 @@ import { injectIntl } from 'react-intl'; import { connect } from 'react-redux'; +import { getFeatures } from 'soapbox/utils/features'; + import { changeCompose, submitCompose, @@ -13,24 +15,29 @@ import { } from '../../../actions/compose'; import ComposeForm from '../components/compose_form'; -const mapStateToProps = state => ({ - text: state.getIn(['compose', 'text']), - suggestions: state.getIn(['compose', 'suggestions']), - spoiler: state.getIn(['compose', 'spoiler']), - spoilerText: state.getIn(['compose', 'spoiler_text']), - privacy: state.getIn(['compose', 'privacy']), - focusDate: state.getIn(['compose', 'focusDate']), - caretPosition: state.getIn(['compose', 'caretPosition']), - isSubmitting: state.getIn(['compose', 'is_submitting']), - isChangingUpload: state.getIn(['compose', 'is_changing_upload']), - isUploading: state.getIn(['compose', 'is_uploading']), - showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']), - anyMedia: state.getIn(['compose', 'media_attachments']).size > 0, - isModalOpen: state.get('modals').size && state.get('modals').last().modalType === 'COMPOSE', - maxTootChars: state.getIn(['instance', 'configuration', 'statuses', 'max_characters']), - scheduledAt: state.getIn(['compose', 'schedule']), - scheduledStatusCount: state.get('scheduled_statuses').size, -}); +const mapStateToProps = state => { + const instance = state.get('instance'); + + return { + text: state.getIn(['compose', 'text']), + suggestions: state.getIn(['compose', 'suggestions']), + spoiler: state.getIn(['compose', 'spoiler']), + spoilerText: state.getIn(['compose', 'spoiler_text']), + privacy: state.getIn(['compose', 'privacy']), + focusDate: state.getIn(['compose', 'focusDate']), + caretPosition: state.getIn(['compose', 'caretPosition']), + isSubmitting: state.getIn(['compose', 'is_submitting']), + isChangingUpload: state.getIn(['compose', 'is_changing_upload']), + isUploading: state.getIn(['compose', 'is_uploading']), + showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']), + anyMedia: state.getIn(['compose', 'media_attachments']).size > 0, + isModalOpen: state.get('modals').size && state.get('modals').last().modalType === 'COMPOSE', + maxTootChars: state.getIn(['instance', 'configuration', 'statuses', 'max_characters']), + scheduledAt: state.getIn(['compose', 'schedule']), + scheduledStatusCount: state.get('scheduled_statuses').size, + features: getFeatures(instance), + }; +}; const mapDispatchToProps = (dispatch) => ({ diff --git a/app/soapbox/features/compose/containers/markdown_button_container.js b/app/soapbox/features/compose/containers/markdown_button_container.js index 86868c452..4001f3c92 100644 --- a/app/soapbox/features/compose/containers/markdown_button_container.js +++ b/app/soapbox/features/compose/containers/markdown_button_container.js @@ -1,17 +1,11 @@ import { connect } from 'react-redux'; -import { getFeatures } from 'soapbox/utils/features'; - import { changeComposeContentType } from '../../../actions/compose'; import MarkdownButton from '../components/markdown_button'; const mapStateToProps = (state, { intl }) => { - const instance = state.get('instance'); - const features = getFeatures(instance); - return { active: state.getIn(['compose', 'content_type']) === 'text/markdown', - unavailable: !features.richText, }; }; diff --git a/app/soapbox/utils/features.js b/app/soapbox/utils/features.js index 44621a322..8f636eea0 100644 --- a/app/soapbox/utils/features.js +++ b/app/soapbox/utils/features.js @@ -23,6 +23,17 @@ export const getFeatures = createSelector([instance => instance], instance => { const federation = instance.getIn(['pleroma', 'metadata', 'federation'], ImmutableMap()); return Object.assign({ + media: true, + privacyScopes: true, + spoilers: true, + polls: any([ + v.software === MASTODON && gte(v.version, '2.8.0'), + v.software === PLEROMA, + ]), + scheduledStatuses: any([ + v.software === MASTODON && gte(v.version, '2.7.0'), + v.software === PLEROMA, + ]), bookmarks: any([ v.software === MASTODON && gte(v.compatVersion, '3.1.0'), v.software === PLEROMA && gte(v.version, '0.9.9'),