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'),