import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
-const APPROX_HASHTAG_RE = /(?:^|[^\/\)\w])#(\S+)/i;
-
// Components.
import ComposerOptions from '../../composer/options';
import ComposerPublisher from '../../composer/publisher';
import ComposerTextarea from '../../composer/textarea';
import ComposerUploadForm from '../../composer/upload_form';
import ComposerPollForm from '../../composer/poll_form';
-import ComposerWarning from '../../composer/warning';
-import ComposerHashtagWarning from '../../composer/hashtag_warning';
-import ComposerDirectWarning from '../../composer/direct_warning';
+import WarningContainer from '../containers/warning_container';
// Utils.
import { countableText } from 'flavours/glitch/util/counter';
return (
<div className='composer'>
- {privacy === 'direct' ? <ComposerDirectWarning /> : null}
- {privacy === 'private' && amUnlocked ? <ComposerWarning /> : null}
- {privacy !== 'public' && APPROX_HASHTAG_RE.test(text) ? <ComposerHashtagWarning /> : null}
+ <WarningContainer />
+
{inReplyTo && (
<ComposerReply
status={inReplyTo}
onCancel={onCancelReply}
/>
)}
+
<ComposerSpoiler
hidden={!spoiler}
intl={intl}
text={spoilerText}
ref={handleRefSpoilerText}
/>
+
<ComposerTextarea
advancedOptions={advancedOptions}
autoFocus={!showSearch && !isMobile(window.innerWidth, layout)}
--- /dev/null
+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>
+ );
+ }
+
+}
--- /dev/null
+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);
+++ /dev/null
-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 = {};
+++ /dev/null
-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 = {};
+++ /dev/null
-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 = {};