Add status content type dropdown to compose box.
Signed-off-by: Thibaut Girka <thib@sitedethib.com>
This commit is contained in:
parent
14d7ddcb1c
commit
f34a402a94
6 changed files with 80 additions and 1 deletions
|
@ -46,6 +46,7 @@ export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
|
|||
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
|
||||
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
|
||||
export const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE';
|
||||
export const COMPOSE_CONTENT_TYPE_CHANGE = 'COMPOSE_CONTENT_TYPE_CHANGE';
|
||||
|
||||
export const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT';
|
||||
|
||||
|
@ -147,6 +148,7 @@ export function submitCompose(routerHistory) {
|
|||
}
|
||||
api(getState).post('/api/v1/statuses', {
|
||||
status,
|
||||
content_type: getState().getIn(['compose', 'content_type']),
|
||||
in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
|
||||
media_ids: media.map(item => item.get('id')),
|
||||
sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0),
|
||||
|
@ -517,6 +519,13 @@ export function changeComposeVisibility(value) {
|
|||
};
|
||||
};
|
||||
|
||||
export function changeComposeContentType(value) {
|
||||
return {
|
||||
type: COMPOSE_CONTENT_TYPE_CHANGE,
|
||||
value,
|
||||
};
|
||||
};
|
||||
|
||||
export function insertEmojiCompose(position, emoji) {
|
||||
return {
|
||||
type: COMPOSE_EMOJI_INSERT,
|
||||
|
|
|
@ -38,6 +38,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
suggestions: ImmutablePropTypes.list,
|
||||
spoiler: PropTypes.bool,
|
||||
privacy: PropTypes.string,
|
||||
contentType: PropTypes.string,
|
||||
spoilerText: PropTypes.string,
|
||||
focusDate: PropTypes.instanceOf(Date),
|
||||
caretPosition: PropTypes.number,
|
||||
|
@ -66,6 +67,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
preselectOnReply: PropTypes.bool,
|
||||
onChangeSpoilerness: PropTypes.func,
|
||||
onChangeVisibility: PropTypes.func,
|
||||
onChangeContentType: PropTypes.func,
|
||||
onMount: PropTypes.func,
|
||||
onUnmount: PropTypes.func,
|
||||
onPaste: PropTypes.func,
|
||||
|
@ -285,10 +287,12 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
media,
|
||||
onChangeSpoilerness,
|
||||
onChangeVisibility,
|
||||
onChangeContentType,
|
||||
onClearSuggestions,
|
||||
onFetchSuggestions,
|
||||
onPaste,
|
||||
privacy,
|
||||
contentType,
|
||||
sensitive,
|
||||
showSearch,
|
||||
sideArm,
|
||||
|
@ -356,9 +360,11 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
advancedOptions={advancedOptions}
|
||||
disabled={isSubmitting}
|
||||
onChangeVisibility={onChangeVisibility}
|
||||
onChangeContentType={onChangeContentType}
|
||||
onToggleSpoiler={spoilersAlwaysOn ? null : onChangeSpoilerness}
|
||||
onUpload={onPaste}
|
||||
privacy={privacy}
|
||||
contentType={contentType}
|
||||
sensitive={sensitive || (spoilersAlwaysOn && spoilerText && spoilerText.length > 0)}
|
||||
spoiler={spoilersAlwaysOn ? (spoilerText && spoilerText.length > 0) : spoiler}
|
||||
/>
|
||||
|
@ -369,6 +375,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
onSecondarySubmit={handleSecondarySubmit}
|
||||
onSubmit={handleSubmit}
|
||||
privacy={privacy}
|
||||
contentType={contentType}
|
||||
sideArm={sideArm}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -29,6 +29,10 @@ const messages = defineMessages({
|
|||
defaultMessage: 'Adjust status privacy',
|
||||
id: 'privacy.change',
|
||||
},
|
||||
content_type: {
|
||||
defaultMessage: 'Content type',
|
||||
id: 'content-type.change',
|
||||
},
|
||||
direct_long: {
|
||||
defaultMessage: 'Post to mentioned users only',
|
||||
id: 'privacy.direct.long',
|
||||
|
@ -41,6 +45,10 @@ const messages = defineMessages({
|
|||
defaultMessage: 'Draw something',
|
||||
id: 'compose.attach.doodle',
|
||||
},
|
||||
html: {
|
||||
defaultMessage: 'HTML',
|
||||
id: 'compose.content-type.html',
|
||||
},
|
||||
local_only_long: {
|
||||
defaultMessage: 'Do not post to other instances',
|
||||
id: 'advanced_options.local-only.long',
|
||||
|
@ -49,6 +57,14 @@ const messages = defineMessages({
|
|||
defaultMessage: 'Local-only',
|
||||
id: 'advanced_options.local-only.short',
|
||||
},
|
||||
markdown: {
|
||||
defaultMessage: 'Markdown',
|
||||
id: 'compose.content-type.markdown',
|
||||
},
|
||||
plain: {
|
||||
defaultMessage: 'Plain text',
|
||||
id: 'compose.content-type.plain',
|
||||
},
|
||||
private_long: {
|
||||
defaultMessage: 'Post to followers only',
|
||||
id: 'privacy.private.long',
|
||||
|
@ -113,6 +129,7 @@ class ComposerOptions extends ImmutablePureComponent {
|
|||
intl: PropTypes.object.isRequired,
|
||||
onChangeAdvancedOption: PropTypes.func,
|
||||
onChangeVisibility: PropTypes.func,
|
||||
onChangeContentType: PropTypes.func,
|
||||
onTogglePoll: PropTypes.func,
|
||||
onDoodleOpen: PropTypes.func,
|
||||
onModalClose: PropTypes.func,
|
||||
|
@ -120,6 +137,7 @@ class ComposerOptions extends ImmutablePureComponent {
|
|||
onToggleSpoiler: PropTypes.func,
|
||||
onUpload: PropTypes.func,
|
||||
privacy: PropTypes.string,
|
||||
contentType: PropTypes.string,
|
||||
resetFileKey: PropTypes.number,
|
||||
spoiler: PropTypes.bool,
|
||||
};
|
||||
|
@ -162,6 +180,7 @@ class ComposerOptions extends ImmutablePureComponent {
|
|||
const {
|
||||
acceptContentTypes,
|
||||
advancedOptions,
|
||||
contentType,
|
||||
disabled,
|
||||
allowMedia,
|
||||
hasMedia,
|
||||
|
@ -169,6 +188,7 @@ class ComposerOptions extends ImmutablePureComponent {
|
|||
hasPoll,
|
||||
intl,
|
||||
onChangeAdvancedOption,
|
||||
onChangeContentType,
|
||||
onChangeVisibility,
|
||||
onTogglePoll,
|
||||
onModalClose,
|
||||
|
@ -208,6 +228,24 @@ class ComposerOptions extends ImmutablePureComponent {
|
|||
},
|
||||
};
|
||||
|
||||
const contentTypeItems = {
|
||||
plain: {
|
||||
icon: 'file',
|
||||
name: 'text/plain',
|
||||
text: <FormattedMessage {...messages.plain} />,
|
||||
},
|
||||
html: {
|
||||
icon: 'file-text',
|
||||
name: 'text/html',
|
||||
text: <FormattedMessage {...messages.html} />,
|
||||
},
|
||||
markdown: {
|
||||
icon: 'file-text',
|
||||
name: 'text/markdown',
|
||||
text: <FormattedMessage {...messages.markdown} />,
|
||||
},
|
||||
};
|
||||
|
||||
// The result.
|
||||
return (
|
||||
<div className='composer--options'>
|
||||
|
@ -272,6 +310,19 @@ class ComposerOptions extends ImmutablePureComponent {
|
|||
title={intl.formatMessage(messages.change_privacy)}
|
||||
value={privacy}
|
||||
/>
|
||||
<Dropdown
|
||||
icon="code"
|
||||
items={[
|
||||
contentTypeItems.plain,
|
||||
contentTypeItems.html,
|
||||
contentTypeItems.markdown,
|
||||
]}
|
||||
onChange={onChangeContentType}
|
||||
onModalClose={onModalClose}
|
||||
onModalOpen={onModalOpen}
|
||||
title={intl.formatMessage(messages.content_type)}
|
||||
value={contentType}
|
||||
/>
|
||||
{onToggleSpoiler && (
|
||||
<TextIconButton
|
||||
active={spoiler}
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
changeComposeSpoilerText,
|
||||
changeComposeSpoilerness,
|
||||
changeComposeVisibility,
|
||||
changeComposeContentType,
|
||||
clearComposeSuggestions,
|
||||
fetchComposeSuggestions,
|
||||
insertEmojiCompose,
|
||||
|
@ -57,6 +58,7 @@ function mapStateToProps (state) {
|
|||
media: state.getIn(['compose', 'media_attachments']),
|
||||
preselectDate: state.getIn(['compose', 'preselectDate']),
|
||||
privacy: state.getIn(['compose', 'privacy']),
|
||||
contentType: state.getIn(['compose', 'content_type']),
|
||||
sideArm: sideArmPrivacy,
|
||||
sensitive: state.getIn(['compose', 'sensitive']),
|
||||
showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
|
||||
|
@ -98,6 +100,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
|||
dispatch(changeComposeSpoilerText(text));
|
||||
},
|
||||
|
||||
onChangeContentType(value) {
|
||||
dispatch(changeComposeContentType(value));
|
||||
},
|
||||
|
||||
onPaste(files) {
|
||||
dispatch(uploadCompose(files));
|
||||
},
|
||||
|
|
|
@ -29,7 +29,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
|||
},
|
||||
});
|
||||
|
||||
export default @connect(mapStateToProps, mapDispatchToProps)
|
||||
export default @connect(mapStateToProps)
|
||||
@injectIntl
|
||||
class Compose extends React.PureComponent {
|
||||
static propTypes = {
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
COMPOSE_SPOILERNESS_CHANGE,
|
||||
COMPOSE_SPOILER_TEXT_CHANGE,
|
||||
COMPOSE_VISIBILITY_CHANGE,
|
||||
COMPOSE_CONTENT_TYPE_CHANGE,
|
||||
COMPOSE_EMOJI_INSERT,
|
||||
COMPOSE_UPLOAD_CHANGE_REQUEST,
|
||||
COMPOSE_UPLOAD_CHANGE_SUCCESS,
|
||||
|
@ -66,6 +67,7 @@ const initialState = ImmutableMap({
|
|||
spoiler: false,
|
||||
spoiler_text: '',
|
||||
privacy: null,
|
||||
content_type: 'text/plain',
|
||||
text: '',
|
||||
focusDate: null,
|
||||
caretPosition: null,
|
||||
|
@ -310,6 +312,10 @@ export default function compose(state = initialState, action) {
|
|||
return state
|
||||
.set('privacy', action.value)
|
||||
.set('idempotencyKey', uuid());
|
||||
case COMPOSE_CONTENT_TYPE_CHANGE:
|
||||
return state
|
||||
.set('content_type', action.value)
|
||||
.set('idempotencyKey', uuid());
|
||||
case COMPOSE_CHANGE:
|
||||
return state
|
||||
.set('text', action.text)
|
||||
|
|
Loading…
Reference in a new issue