diff options
Diffstat (limited to 'app/assets/javascripts/components/features/compose')
-rw-r--r-- | app/assets/javascripts/components/features/compose/components/compose_form.jsx | 70 | ||||
-rw-r--r-- | app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx | 4 |
2 files changed, 44 insertions, 30 deletions
diff --git a/app/assets/javascripts/components/features/compose/components/compose_form.jsx b/app/assets/javascripts/components/features/compose/components/compose_form.jsx index 46b62964a..9edc01ed7 100644 --- a/app/assets/javascripts/components/features/compose/components/compose_form.jsx +++ b/app/assets/javascripts/components/features/compose/components/compose_form.jsx @@ -10,7 +10,7 @@ import { debounce } from 'react-decoration'; import UploadButtonContainer from '../containers/upload_button_container'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import Toggle from 'react-toggle'; -import { Motion, spring } from 'react-motion'; +import Collapsable from '../../../components/collapsable'; const messages = defineMessages({ placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' }, @@ -36,6 +36,8 @@ const ComposeForm = React.createClass({ in_reply_to: ImmutablePropTypes.map, media_count: React.PropTypes.number, me: React.PropTypes.number, + needsPrivacyWarning: React.PropTypes.bool, + mentionedDomains: React.PropTypes.array.isRequired, onChange: React.PropTypes.func.isRequired, onSubmit: React.PropTypes.func.isRequired, onCancelReply: React.PropTypes.func.isRequired, @@ -117,16 +119,29 @@ const ComposeForm = React.createClass({ }, render () { - const { intl } = this.props; - let replyArea = ''; - let publishText = ''; - const disabled = this.props.is_submitting || this.props.is_uploading; + const { intl, needsPrivacyWarning, mentionedDomains } = this.props; + const disabled = this.props.is_submitting || this.props.is_uploading; + + let replyArea = ''; + let publishText = ''; + let privacyWarning = ''; + let reply_to_other = !!this.props.in_reply_to && (this.props.in_reply_to.getIn(['account', 'id']) !== this.props.me); if (this.props.in_reply_to) { replyArea = <ReplyIndicator status={this.props.in_reply_to} onCancel={this.props.onCancelReply} />; } - let reply_to_other = !!this.props.in_reply_to && (this.props.in_reply_to.getIn(['account', 'id']) !== this.props.me); + if (needsPrivacyWarning) { + privacyWarning = ( + <div className='compose-form__warning'> + <FormattedMessage + id='compose_form.privacy_disclaimer' + defaultMessage='Your private status will be delivered to mentioned users on {domains}. Do you trust {domainsCount, plural, one {that server} other {those servers}} to not leak your status?' + values={{ domains: <strong>{mentionedDomains.join(', ')}</strong>, domainsCount: mentionedDomains.length }} + /> + </div> + ); + } if (this.props.private) { publishText = <span><i className='fa fa-lock' /> {intl.formatMessage(messages.publish)}</span>; @@ -136,14 +151,13 @@ const ComposeForm = React.createClass({ return ( <div style={{ padding: '10px' }}> - <Motion defaultStyle={{ opacity: !this.props.spoiler ? 0 : 100, height: !this.props.spoiler ? 50 : 0 }} style={{ opacity: spring(!this.props.spoiler ? 0 : 100), height: spring(!this.props.spoiler ? 0 : 50) }}> - {({ opacity, height }) => - <div className="spoiler-input" style={{ height: `${height}px`, overflow: 'hidden', opacity: opacity / 100 }}> - <input placeholder={intl.formatMessage(messages.spoiler_placeholder)} value={this.props.spoiler_text} onChange={this.handleChangeSpoilerText} type="text" className="spoiler-input__input" /> - </div> - } - </Motion> + <Collapsable isVisible={this.props.spoiler} fullHeight={50}> + <div className="spoiler-input"> + <input placeholder={intl.formatMessage(messages.spoiler_placeholder)} value={this.props.spoiler_text} onChange={this.handleChangeSpoilerText} type="text" className="spoiler-input__input" /> + </div> + </Collapsable> + {privacyWarning} {replyArea} <AutosuggestTextarea @@ -176,23 +190,19 @@ const ComposeForm = React.createClass({ <span className='compose-form__label__text'><FormattedMessage id='compose_form.private' defaultMessage='Mark as private' /></span> </label> - <Motion defaultStyle={{ opacity: (this.props.private || reply_to_other) ? 0 : 100, height: (this.props.private || reply_to_other) ? 39.5 : 0 }} style={{ opacity: spring((this.props.private || reply_to_other) ? 0 : 100), height: spring((this.props.private || reply_to_other) ? 0 : 39.5) }}> - {({ opacity, height }) => - <label className='compose-form__label' style={{ height: `${height}px`, overflow: 'hidden', opacity: opacity / 100 }}> - <Toggle checked={this.props.unlisted} onChange={this.handleChangeListability} /> - <span className='compose-form__label__text'><FormattedMessage id='compose_form.unlisted' defaultMessage='Do not display in public timeline' /></span> - </label> - } - </Motion> - - <Motion defaultStyle={{ opacity: 0, height: 0 }} style={{ opacity: spring(this.props.media_count === 0 ? 0 : 100), height: spring(this.props.media_count === 0 ? 0 : 39.5) }}> - {({ opacity, height }) => - <label className='compose-form__label' style={{ height: `${height}px`, overflow: 'hidden', opacity: opacity / 100 }}> - <Toggle checked={this.props.sensitive} onChange={this.handleChangeSensitivity} /> - <span className='compose-form__label__text'><FormattedMessage id='compose_form.sensitive' defaultMessage='Mark media as sensitive' /></span> - </label> - } - </Motion> + <Collapsable isVisible={!(this.props.private || reply_to_other)} fullHeight={39.5}> + <label className='compose-form__label'> + <Toggle checked={this.props.unlisted} onChange={this.handleChangeListability} /> + <span className='compose-form__label__text'><FormattedMessage id='compose_form.unlisted' defaultMessage='Do not display in public timeline' /></span> + </label> + </Collapsable> + + <Collapsable isVisible={this.props.media_count > 0} fullHeight={39.5}> + <label className='compose-form__label'> + <Toggle checked={this.props.sensitive} onChange={this.handleChangeSensitivity} /> + <span className='compose-form__label__text'><FormattedMessage id='compose_form.sensitive' defaultMessage='Mark media as sensitive' /></span> + </label> + </Collapsable> </div> ); } diff --git a/app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx b/app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx index c027875cd..2671ea618 100644 --- a/app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx +++ b/app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx @@ -19,6 +19,8 @@ const makeMapStateToProps = () => { const getStatus = makeGetStatus(); const mapStateToProps = function (state, props) { + const mentionedUsernamesWithDomains = state.getIn(['compose', 'text']).match(/(?:^|[^\/\w])@([a-z0-9_]+@[a-z0-9\.\-]+)/ig); + return { text: state.getIn(['compose', 'text']), suggestion_token: state.getIn(['compose', 'suggestion_token']), @@ -34,6 +36,8 @@ const makeMapStateToProps = () => { in_reply_to: getStatus(state, state.getIn(['compose', 'in_reply_to'])), media_count: state.getIn(['compose', 'media_attachments']).size, me: state.getIn(['compose', 'me']), + needsPrivacyWarning: state.getIn(['compose', 'private']) && mentionedUsernamesWithDomains !== null, + mentionedDomains: mentionedUsernamesWithDomains !== null ? [...new Set(mentionedUsernamesWithDomains.map(item => item.split('@')[2]))] : [] }; }; |