Refactor Compose*Warning → ContainerWarning

Regression: only one warning at a time
pull/574/head
Thibaut Girka 2019-04-20 22:05:09 +02:00 committed by ThibG
parent 1bc4b8a0a5
commit f72af5794d
6 changed files with 75 additions and 171 deletions

View File

@ -4,8 +4,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
const APPROX_HASHTAG_RE = /(?:^|[^\/\)\w])#(\S+)/i;
// Components. // Components.
import ComposerOptions from '../../composer/options'; import ComposerOptions from '../../composer/options';
import ComposerPublisher from '../../composer/publisher'; import ComposerPublisher from '../../composer/publisher';
@ -14,9 +12,7 @@ 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';
import ComposerWarning from '../../composer/warning'; import WarningContainer from '../containers/warning_container';
import ComposerHashtagWarning from '../../composer/hashtag_warning';
import ComposerDirectWarning from '../../composer/direct_warning';
// Utils. // Utils.
import { countableText } from 'flavours/glitch/util/counter'; import { countableText } from 'flavours/glitch/util/counter';
@ -321,9 +317,8 @@ class ComposeForm extends ImmutablePureComponent {
return ( return (
<div className='composer'> <div className='composer'>
{privacy === 'direct' ? <ComposerDirectWarning /> : null} <WarningContainer />
{privacy === 'private' && amUnlocked ? <ComposerWarning /> : null}
{privacy !== 'public' && APPROX_HASHTAG_RE.test(text) ? <ComposerHashtagWarning /> : null}
{inReplyTo && ( {inReplyTo && (
<ComposerReply <ComposerReply
status={inReplyTo} status={inReplyTo}
@ -331,6 +326,7 @@ class ComposeForm extends ImmutablePureComponent {
onCancel={onCancelReply} onCancel={onCancelReply}
/> />
)} )}
<ComposerSpoiler <ComposerSpoiler
hidden={!spoiler} hidden={!spoiler}
intl={intl} intl={intl}
@ -340,6 +336,7 @@ class ComposeForm extends ImmutablePureComponent {
text={spoilerText} text={spoilerText}
ref={handleRefSpoilerText} ref={handleRefSpoilerText}
/> />
<ComposerTextarea <ComposerTextarea
advancedOptions={advancedOptions} advancedOptions={advancedOptions}
autoFocus={!showSearch && !isMobile(window.innerWidth, layout)} autoFocus={!showSearch && !isMobile(window.innerWidth, layout)}

View File

@ -0,0 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';
import Motion from 'flavours/glitch/util/optional_motion';
import spring from 'react-motion/lib/spring';
export default class Warning extends React.PureComponent {
static propTypes = {
message: PropTypes.node.isRequired,
};
render () {
const { message } = this.props;
return (
<Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
{({ opacity, scaleX, scaleY }) => (
<div className='composer--warning' style={{ opacity: opacity, transform: `scale(${scaleX}, ${scaleY})` }}>
{message}
</div>
)}
</Motion>
);
}
}

View File

@ -0,0 +1,44 @@
import React from 'react';
import { connect } from 'react-redux';
import Warning from '../components/warning';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { me } from 'flavours/glitch/util/initial_state';
const APPROX_HASHTAG_RE = /(?:^|[^\/\)\w])#(\w*[a-zA-Z·]\w*)/i;
const mapStateToProps = state => ({
needsLockWarning: state.getIn(['compose', 'privacy']) === 'private' && !state.getIn(['accounts', me, 'locked']),
hashtagWarning: state.getIn(['compose', 'privacy']) !== 'public' && APPROX_HASHTAG_RE.test(state.getIn(['compose', 'text'])),
directMessageWarning: state.getIn(['compose', 'privacy']) === 'direct',
});
const WarningWrapper = ({ needsLockWarning, hashtagWarning, directMessageWarning }) => {
if (needsLockWarning) {
return <Warning message={<FormattedMessage id='compose_form.lock_disclaimer' defaultMessage='Your account is not {locked}. Anyone can follow you to view your follower-only posts.' values={{ locked: <a href='/settings/profile'><FormattedMessage id='compose_form.lock_disclaimer.lock' defaultMessage='locked' /></a> }} />} />;
}
if (hashtagWarning) {
return <Warning message={<FormattedMessage id='compose_form.hashtag_warning' defaultMessage="This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag." />} />;
}
if (directMessageWarning) {
const message = (
<span>
<FormattedMessage id='compose_form.direct_message_warning' defaultMessage='This toot will only be sent to all the mentioned users.' /> <a href='/terms' target='_blank'><FormattedMessage id='compose_form.direct_message_warning_learn_more' defaultMessage='Learn more' /></a>
</span>
);
return <Warning message={message} />;
}
return null;
};
WarningWrapper.propTypes = {
needsLockWarning: PropTypes.bool,
hashtagWarning: PropTypes.bool,
directMessageWarning: PropTypes.bool,
};
export default connect(mapStateToProps)(WarningWrapper);

View File

@ -1,55 +0,0 @@
import React from 'react';
import Motion from 'flavours/glitch/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { defineMessages, FormattedMessage } from 'react-intl';
import { termsLink} from 'flavours/glitch/util/backend_links';
// This is the spring used with our motion.
const motionSpring = spring(1, { damping: 35, stiffness: 400 });
// Messages.
const messages = defineMessages({
disclaimer: {
defaultMessage: 'This toot will only be sent to all the mentioned users.',
id: 'compose_form.direct_message_warning',
},
learn_more: {
defaultMessage: 'Learn more',
id: 'compose_form.direct_message_warning_learn_more'
}
});
// The component.
export default function ComposerDirectWarning () {
return (
<Motion
defaultStyle={{
opacity: 0,
scaleX: 0.85,
scaleY: 0.75,
}}
style={{
opacity: motionSpring,
scaleX: motionSpring,
scaleY: motionSpring,
}}
>
{({ opacity, scaleX, scaleY }) => (
<div
className='composer--warning'
style={{
opacity: opacity,
transform: `scale(${scaleX}, ${scaleY})`,
}}
>
<span>
<FormattedMessage {...messages.disclaimer} />
{ termsLink !== undefined && <a href={termsLink} target='_blank'><FormattedMessage {...messages.learn_more} /></a> }
</span>
</div>
)}
</Motion>
);
}
ComposerDirectWarning.propTypes = {};

View File

@ -1,49 +0,0 @@
import React from 'react';
import Motion from 'flavours/glitch/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { defineMessages, FormattedMessage } from 'react-intl';
// This is the spring used with our motion.
const motionSpring = spring(1, { damping: 35, stiffness: 400 });
// Messages.
const messages = defineMessages({
disclaimer: {
defaultMessage: 'This toot won\'t be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.',
id: 'compose_form.hashtag_warning',
},
});
// The component.
export default function ComposerHashtagWarning () {
return (
<Motion
defaultStyle={{
opacity: 0,
scaleX: 0.85,
scaleY: 0.75,
}}
style={{
opacity: motionSpring,
scaleX: motionSpring,
scaleY: motionSpring,
}}
>
{({ opacity, scaleX, scaleY }) => (
<div
className='composer--warning'
style={{
opacity: opacity,
transform: `scale(${scaleX}, ${scaleY})`,
}}
>
<FormattedMessage
{...messages.disclaimer}
/>
</div>
)}
</Motion>
);
}
ComposerHashtagWarning.propTypes = {};

View File

@ -1,59 +0,0 @@
import React from 'react';
import Motion from 'flavours/glitch/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { defineMessages, FormattedMessage } from 'react-intl';
import { profileLink } from 'flavours/glitch/util/backend_links';
// This is the spring used with our motion.
const motionSpring = spring(1, { damping: 35, stiffness: 400 });
// Messages.
const messages = defineMessages({
disclaimer: {
defaultMessage: 'Your account is not {locked}. Anyone can follow you to view your follower-only posts.',
id: 'compose_form.lock_disclaimer',
},
locked: {
defaultMessage: 'locked',
id: 'compose_form.lock_disclaimer.lock',
},
});
// The component.
export default function ComposerWarning () {
let lockedLink = <FormattedMessage {...messages.locked} />;
if (profileLink !== undefined) {
lockedLink = <a href={profileLink}>{lockedLink}</a>;
}
return (
<Motion
defaultStyle={{
opacity: 0,
scaleX: 0.85,
scaleY: 0.75,
}}
style={{
opacity: motionSpring,
scaleX: motionSpring,
scaleY: motionSpring,
}}
>
{({ opacity, scaleX, scaleY }) => (
<div
className='composer--warning'
style={{
opacity: opacity,
transform: `scale(${scaleX}, ${scaleY})`,
}}
>
<FormattedMessage
{...messages.disclaimer}
values={{ locked: lockedLink }}
/>
</div>
)}
</Motion>
);
}
ComposerWarning.propTypes = {};