mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-01 00:51:55 +00:00
Refactor Compose*Warning → ContainerWarning
Regression: only one warning at a time
This commit is contained in:
parent
1bc4b8a0a5
commit
f72af5794d
|
@ -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)}
|
||||||
|
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
|
@ -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 = {};
|
|
|
@ -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 = {};
|
|
|
@ -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 = {};
|
|
Loading…
Reference in a new issue