about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOndřej Hruška <ondra@ondrovo.com>2017-09-23 23:11:02 +0200
committerGitHub <noreply@github.com>2017-09-23 23:11:02 +0200
commit67f82775268f57be5506031e65e3155a2618bef9 (patch)
treed776a9faec3bd8d4e9016d50b83ef5ac98c2d12a
parent169d83f5321267c4c424f0fb1a731c7724a38056 (diff)
Add secondary toot button (opt-in) (#153)
Add secondary toot button + other toot button enhancements. 
Squashing so it's easy to revert if needed.
-rw-r--r--app/javascript/glitch/components/local_settings/page/index.js19
-rw-r--r--app/javascript/glitch/reducers/local_settings.js1
-rw-r--r--app/javascript/mastodon/features/compose/components/compose_form.js66
-rw-r--r--app/javascript/mastodon/features/compose/containers/compose_form_container.js7
-rw-r--r--app/javascript/styles/components.scss18
5 files changed, 104 insertions, 7 deletions
diff --git a/app/javascript/glitch/components/local_settings/page/index.js b/app/javascript/glitch/components/local_settings/page/index.js
index cb041c0b8..338d86333 100644
--- a/app/javascript/glitch/components/local_settings/page/index.js
+++ b/app/javascript/glitch/components/local_settings/page/index.js
@@ -16,6 +16,7 @@ const messages = defineMessages({
   layout_auto: {  id: 'layout.auto', defaultMessage: 'Auto' },
   layout_desktop: { id: 'layout.desktop', defaultMessage: 'Desktop' },
   layout_mobile: { id: 'layout.single', defaultMessage: 'Mobile' },
+  side_arm_none: { id: 'settings.side_arm.none', defaultMessage: 'None' },
 });
 
 @injectIntl
@@ -61,6 +62,24 @@ export default class LocalSettingsPage extends React.PureComponent {
         >
           <FormattedMessage id='settings.navbar_under' defaultMessage='Navbar at the bottom (Mobile only)' />
         </LocalSettingsPageItem>
+        <section>
+          <h2><FormattedMessage id='settings.compose_box_opts' defaultMessage='Compose box options' /></h2>
+          <LocalSettingsPageItem
+            settings={settings}
+            item={['side_arm']}
+            id='mastodon-settings--side_arm'
+            options={[
+              { value: 'none', message: intl.formatMessage(messages.side_arm_none) },
+              { value: 'direct', message: intl.formatMessage({ id: 'privacy.direct.short' }) },
+              { value: 'private', message: intl.formatMessage({ id: 'privacy.private.short' }) },
+              { value: 'unlisted', message: intl.formatMessage({ id: 'privacy.unlisted.short' }) },
+              { value: 'public', message: intl.formatMessage({ id: 'privacy.public.short' }) },
+            ]}
+            onChange={onChange}
+          >
+            <FormattedMessage id='settings.side_arm' defaultMessage='Secondary toot button:' />
+          </LocalSettingsPageItem>
+        </section>
       </div>
     ),
     ({ onChange, settings }) => (
diff --git a/app/javascript/glitch/reducers/local_settings.js b/app/javascript/glitch/reducers/local_settings.js
index 386d59ceb..813e130ca 100644
--- a/app/javascript/glitch/reducers/local_settings.js
+++ b/app/javascript/glitch/reducers/local_settings.js
@@ -52,6 +52,7 @@ const initialState = ImmutableMap({
   layout    : 'auto',
   stretch   : true,
   navbar_under : false,
+  side_arm  : 'none',
   collapsed : ImmutableMap({
     enabled     : true,
     auto        : ImmutableMap({
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index f6b5cf0be..1d60ffe83 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -51,11 +51,13 @@ export default class ComposeForm extends ImmutablePureComponent {
     onSubmit: PropTypes.func.isRequired,
     onClearSuggestions: PropTypes.func.isRequired,
     onFetchSuggestions: PropTypes.func.isRequired,
+    onPrivacyChange: PropTypes.func.isRequired,
     onSuggestionSelected: PropTypes.func.isRequired,
     onChangeSpoilerText: PropTypes.func.isRequired,
     onPaste: PropTypes.func.isRequired,
     onPickEmoji: PropTypes.func.isRequired,
     showSearch: PropTypes.bool,
+    settings : ImmutablePropTypes.map.isRequired,
   };
 
   static defaultProps = {
@@ -72,6 +74,11 @@ export default class ComposeForm extends ImmutablePureComponent {
     }
   }
 
+  handleSubmit2 = () => {
+    this.props.onPrivacyChange(this.props.settings.get('side_arm'));
+    this.handleSubmit();
+  }
+
   handleSubmit = () => {
     if (this.props.text !== this.autosuggestTextarea.textarea.value) {
       // Something changed the text inside the textarea (e.g. browser extensions like Grammarly)
@@ -157,13 +164,42 @@ export default class ComposeForm extends ImmutablePureComponent {
     const maybeEye = (this.props.advanced_options && this.props.advanced_options.do_not_federate) ? ' 👁️' : '';
     const text     = [this.props.spoiler_text, countableText(this.props.text), maybeEye].join('');
 
+    const sideArmVisibility = this.props.settings.get('side_arm');
+    let showSideArm = sideArmVisibility !== 'none';
+
     let publishText = '';
 
-    if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
-      publishText = <span className='compose-form__publish-private'><i className='fa fa-lock' /> {intl.formatMessage(messages.publish)}</span>;
-    } else {
-      publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
-    }
+    const privacyIcons = {
+      none: '',
+      public: 'globe',
+      unlisted: 'unlock-alt',
+      private: 'lock',
+      direct: 'envelope',
+    };
+
+    publishText = (
+      <span>
+        {
+          (this.props.settings.get('stretch') || !showSideArm) ?
+            <i
+              className={`fa fa-${privacyIcons[this.props.privacy]}`}
+              style={{ paddingRight: '5px' }}
+            /> :
+            ''
+        }
+        {intl.formatMessage(messages.publish)}
+      </span>
+    );
+
+    // side-arm
+    let publishText2 = (
+      <i
+        className={`fa fa-${privacyIcons[sideArmVisibility]}`}
+        aria-label={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${sideArmVisibility}.short` })}`}
+      />
+    );
+
+    const submitDisabled = disabled || this.props.is_uploading || length(text) > 500 || (text.length !== 0 && text.trim().length === 0);
 
     return (
       <div className='compose-form'>
@@ -215,7 +251,25 @@ export default class ComposeForm extends ImmutablePureComponent {
 
           <div className='compose-form__publish'>
             <div className='character-counter__wrapper'><CharacterCounter max={500} text={text} /></div>
-            <div className='compose-form__publish-button-wrapper'><Button text={publishText} onClick={this.handleSubmit} disabled={disabled || this.props.is_uploading || length(text) > 500 || (text.length !== 0 && text.trim().length === 0)} block /></div>
+            <div className='compose-form__publish-button-wrapper'>
+              {
+                showSideArm ?
+                  <Button
+                    className='compose-form__publish__side-arm'
+                    text={publishText2}
+                    onClick={this.handleSubmit2}
+                    disabled={submitDisabled}
+                  /> :
+                  ''
+              }
+              <Button
+                className='compose-form__publish__primary'
+                text={publishText}
+                onClick={this.handleSubmit}
+                disabled={submitDisabled}
+                block
+              />
+            </div>
           </div>
         </div>
       </div>
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
index 1911edbf9..4e8cd2279 100644
--- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js
+++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
@@ -1,6 +1,6 @@
 import { connect } from 'react-redux';
 import ComposeForm from '../components/compose_form';
-import { uploadCompose } from '../../../actions/compose';
+import { changeComposeVisibility, uploadCompose } from '../../../actions/compose';
 import {
   changeCompose,
   submitCompose,
@@ -25,6 +25,7 @@ const mapStateToProps = state => ({
   is_uploading: state.getIn(['compose', 'is_uploading']),
   me: state.getIn(['compose', 'me']),
   showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
+  settings: state.get('local_settings'),
 });
 
 const mapDispatchToProps = (dispatch) => ({
@@ -33,6 +34,10 @@ const mapDispatchToProps = (dispatch) => ({
     dispatch(changeCompose(text));
   },
 
+  onPrivacyChange (value) {
+    dispatch(changeComposeVisibility(value));
+  },
+
   onSubmit () {
     dispatch(submitCompose());
   },
diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss
index f087adf9c..2639fd41e 100644
--- a/app/javascript/styles/components.scss
+++ b/app/javascript/styles/components.scss
@@ -421,6 +421,24 @@
 .compose-form__publish-button-wrapper {
   overflow: hidden;
   padding-top: 10px;
+  white-space: nowrap;
+  display: flex;
+
+  button {
+    text-overflow: unset;
+  }
+}
+
+.compose-form__publish__side-arm {
+  padding: 0 !important;
+  width: 4em;
+  text-align: center;
+  opacity: .8;
+  margin-right: 2px;
+}
+
+.compose-form__publish__primary {
+  padding: 0 10px !important;
 }
 
 .emojione {