From d98c54de4f2a7e1230b2dfb9c0d89b0671622072 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 4 Mar 2022 12:47:59 -0600 Subject: [PATCH] ComposeForm: conditional features --- .../compose/components/compose_form.js | 15 ++++--- .../containers/compose_form_container.js | 43 +++++++++++-------- app/soapbox/utils/features.js | 11 +++++ 3 files changed, 44 insertions(+), 25 deletions(-) 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/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/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'),