mirror of
https://github.com/mastodon/mastodon.git
synced 2024-11-28 07:57:45 +00:00
Inline spoiler input
This commit is contained in:
parent
8fd599fb40
commit
f1a22e33e2
|
@ -7,7 +7,6 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
// Components.
|
// Components.
|
||||||
import ComposerOptions from '../../composer/options';
|
import ComposerOptions from '../../composer/options';
|
||||||
import ComposerPublisher from '../../composer/publisher';
|
import ComposerPublisher from '../../composer/publisher';
|
||||||
import ComposerSpoiler from '../../composer/spoiler';
|
|
||||||
import ComposerTextarea from '../../composer/textarea';
|
import ComposerTextarea from '../../composer/textarea';
|
||||||
import ComposerUploadForm from '../../composer/upload_form';
|
import ComposerUploadForm from '../../composer/upload_form';
|
||||||
import ComposerPollForm from '../../composer/poll_form';
|
import ComposerPollForm from '../../composer/poll_form';
|
||||||
|
@ -23,6 +22,7 @@ const messages = defineMessages({
|
||||||
defaultMessage: 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.' },
|
defaultMessage: 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.' },
|
||||||
missingDescriptionConfirm: { id: 'confirmations.missing_media_description.confirm',
|
missingDescriptionConfirm: { id: 'confirmations.missing_media_description.confirm',
|
||||||
defaultMessage: 'Send anyway' },
|
defaultMessage: 'Send anyway' },
|
||||||
|
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @injectIntl
|
export default @injectIntl
|
||||||
|
@ -124,6 +124,25 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleKeyDown = ({ ctrlKey, keyCode, metaKey, altKey }) => {
|
||||||
|
// We submit the status on control/meta + enter.
|
||||||
|
if (keyCode === 13 && (ctrlKey || metaKey)) {
|
||||||
|
handleSubmit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit the status with secondary visibility on alt + enter.
|
||||||
|
if (keyCode === 13 && altKey) {
|
||||||
|
handleSecondarySubmit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the escape key is released, we focus the UI.
|
||||||
|
handleKeyUp = ({ key }) => {
|
||||||
|
if (key === 'Escape') {
|
||||||
|
document.querySelector('.ui').parentElement.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Submits the status.
|
// Submits the status.
|
||||||
handleSubmit = () => {
|
handleSubmit = () => {
|
||||||
const { textarea: { value }, uploadForm } = this;
|
const { textarea: { value }, uploadForm } = this;
|
||||||
|
@ -181,7 +200,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
// Sets a reference to the CW field.
|
// Sets a reference to the CW field.
|
||||||
handleRefSpoilerText = (spoilerComponent) => {
|
handleRefSpoilerText = (spoilerComponent) => {
|
||||||
if (spoilerComponent) {
|
if (spoilerComponent) {
|
||||||
this.spoilerText = spoilerComponent.spoilerText;
|
this.spoilerText = spoilerComponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,14 +279,12 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {
|
const {
|
||||||
handleChangeSpoiler,
|
|
||||||
handleEmoji,
|
handleEmoji,
|
||||||
handleSecondarySubmit,
|
handleSecondarySubmit,
|
||||||
handleSelect,
|
handleSelect,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
handleRefUploadForm,
|
handleRefUploadForm,
|
||||||
handleRefTextarea,
|
handleRefTextarea,
|
||||||
handleRefSpoilerText,
|
|
||||||
} = this;
|
} = this;
|
||||||
const {
|
const {
|
||||||
acceptContentTypes,
|
acceptContentTypes,
|
||||||
|
@ -317,15 +334,23 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
|
|
||||||
<ReplyIndicatorContainer />
|
<ReplyIndicatorContainer />
|
||||||
|
|
||||||
<ComposerSpoiler
|
<div className={`composer--spoiler ${spoiler ? 'composer--spoiler--visible' : ''}`}>
|
||||||
hidden={!spoiler}
|
<label>
|
||||||
intl={intl}
|
<span style={{ display: 'none' }}>{intl.formatMessage(messages.spoiler_placeholder)}</span>
|
||||||
onChange={handleChangeSpoiler}
|
<input
|
||||||
onSubmit={handleSubmit}
|
id='glitch.composer.spoiler.input'
|
||||||
onSecondarySubmit={handleSecondarySubmit}
|
placeholder={intl.formatMessage(messages.spoiler_placeholder)}
|
||||||
text={spoilerText}
|
value={spoilerText}
|
||||||
ref={handleRefSpoilerText}
|
onChange={this.handleChangeSpoiler}
|
||||||
/>
|
onKeyDown={this.handleKeyDown}
|
||||||
|
onKeyUp={this.handleKeyUp}
|
||||||
|
disabled={!spoiler}
|
||||||
|
type='text'
|
||||||
|
className='spoiler-input__input'
|
||||||
|
ref={this.handleRefSpoilerText}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ComposerTextarea
|
<ComposerTextarea
|
||||||
advancedOptions={advancedOptions}
|
advancedOptions={advancedOptions}
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
// Package imports.
|
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { defineMessages, FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
// Utils.
|
|
||||||
import {
|
|
||||||
assignHandlers,
|
|
||||||
hiddenComponent,
|
|
||||||
} from 'flavours/glitch/util/react_helpers';
|
|
||||||
|
|
||||||
// Messages.
|
|
||||||
const messages = defineMessages({
|
|
||||||
placeholder: {
|
|
||||||
defaultMessage: 'Write your warning here',
|
|
||||||
id: 'compose_form.spoiler_placeholder',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Handlers.
|
|
||||||
const handlers = {
|
|
||||||
|
|
||||||
// Handles a keypress.
|
|
||||||
handleKeyDown ({
|
|
||||||
ctrlKey,
|
|
||||||
keyCode,
|
|
||||||
metaKey,
|
|
||||||
altKey,
|
|
||||||
}) {
|
|
||||||
const { onSubmit, onSecondarySubmit } = this.props;
|
|
||||||
|
|
||||||
// We submit the status on control/meta + enter.
|
|
||||||
if (onSubmit && keyCode === 13 && (ctrlKey || metaKey)) {
|
|
||||||
onSubmit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Submit the status with secondary visibility on alt + enter.
|
|
||||||
if (onSecondarySubmit && keyCode === 13 && altKey) {
|
|
||||||
onSecondarySubmit();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleRefSpoilerText (spoilerText) {
|
|
||||||
this.spoilerText = spoilerText;
|
|
||||||
},
|
|
||||||
|
|
||||||
// When the escape key is released, we focus the UI.
|
|
||||||
handleKeyUp ({ key }) {
|
|
||||||
if (key === 'Escape') {
|
|
||||||
document.querySelector('.ui').parentElement.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// The component.
|
|
||||||
export default class ComposerSpoiler extends React.PureComponent {
|
|
||||||
|
|
||||||
// Constructor.
|
|
||||||
constructor (props) {
|
|
||||||
super(props);
|
|
||||||
assignHandlers(this, handlers);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rendering.
|
|
||||||
render () {
|
|
||||||
const { handleKeyDown, handleKeyUp, handleRefSpoilerText } = this.handlers;
|
|
||||||
const {
|
|
||||||
hidden,
|
|
||||||
intl,
|
|
||||||
onChange,
|
|
||||||
text,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
// The result.
|
|
||||||
return (
|
|
||||||
<div className={`composer--spoiler ${hidden ? '' : 'composer--spoiler--visible'}`}>
|
|
||||||
<label>
|
|
||||||
<span {...hiddenComponent}>
|
|
||||||
<FormattedMessage {...messages.placeholder} />
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
id='glitch.composer.spoiler.input'
|
|
||||||
onChange={onChange}
|
|
||||||
onKeyDown={handleKeyDown}
|
|
||||||
onKeyUp={handleKeyUp}
|
|
||||||
placeholder={intl.formatMessage(messages.placeholder)}
|
|
||||||
type='text'
|
|
||||||
value={text}
|
|
||||||
ref={handleRefSpoilerText}
|
|
||||||
disabled={hidden}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Props.
|
|
||||||
ComposerSpoiler.propTypes = {
|
|
||||||
hidden: PropTypes.bool,
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
onChange: PropTypes.func,
|
|
||||||
onSubmit: PropTypes.func,
|
|
||||||
onSecondarySubmit: PropTypes.func,
|
|
||||||
text: PropTypes.string,
|
|
||||||
};
|
|
Loading…
Reference in a new issue