about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/features
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/flavours/glitch/features')
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/dropdown.js8
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js11
-rw-r--r--app/javascript/flavours/glitch/features/picture_in_picture/components/footer.js7
-rw-r--r--app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js7
-rw-r--r--app/javascript/flavours/glitch/features/status/index.js9
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/boost_modal.js37
6 files changed, 62 insertions, 17 deletions
diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown.js b/app/javascript/flavours/glitch/features/compose/components/dropdown.js
index 04ef3964b..abf7cbba1 100644
--- a/app/javascript/flavours/glitch/features/compose/components/dropdown.js
+++ b/app/javascript/flavours/glitch/features/compose/components/dropdown.js
@@ -31,6 +31,8 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
     title: PropTypes.string,
     value: PropTypes.string,
     onChange: PropTypes.func,
+    noModal: PropTypes.bool,
+    container: PropTypes.func,
   };
 
   state = {
@@ -42,10 +44,10 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
 
   //  Toggles opening and closing the dropdown.
   handleToggle = ({ target, type }) => {
-    const { onModalOpen } = this.props;
+    const { onModalOpen, noModal } = this.props;
     const { open } = this.state;
 
-    if (isUserTouching()) {
+    if (!noModal && isUserTouching()) {
       if (this.state.open) {
         this.props.onModalClose();
       } else {
@@ -183,6 +185,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
       items,
       onChange,
       value,
+      container,
     } = this.props;
     const { open, placement } = this.state;
     const computedClass = classNames('composer--options--dropdown', {
@@ -219,6 +222,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
           placement={placement}
           show={open}
           target={this}
+          container={container}
         >
           <DropdownMenu
             items={items}
diff --git a/app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js b/app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js
index ec8d1378e..39f7c7bd1 100644
--- a/app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js
+++ b/app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js
@@ -53,12 +53,13 @@ class PrivacyDropdown extends React.PureComponent {
     value: PropTypes.string.isRequired,
     onChange: PropTypes.func.isRequired,
     noDirect: PropTypes.bool,
+    noModal: PropTypes.bool,
     container: PropTypes.func,
     intl: PropTypes.object.isRequired,
   };
 
   render () {
-    const { value, onChange, onModalOpen, onModalClose, disabled, intl } = this.props;
+    const { value, onChange, onModalOpen, onModalClose, disabled, noDirect, noModal, container, intl } = this.props;
 
     //  We predefine our privacy items so that we can easily pick the
     //  dropdown icon later.
@@ -89,7 +90,11 @@ class PrivacyDropdown extends React.PureComponent {
       },
     };
 
-    const items = [privacyItems.public, privacyItems.unlisted, privacyItems.private, privacyItems.direct];
+    const items = [privacyItems.public, privacyItems.unlisted, privacyItems.private];
+
+    if (!noDirect) {
+      items.push(privacyItems.direct);
+    }
 
     return (
       <Dropdown
@@ -100,6 +105,8 @@ class PrivacyDropdown extends React.PureComponent {
         onModalClose={onModalClose}
         onModalOpen={onModalOpen}
         title={intl.formatMessage(messages.change_privacy)}
+        container={container}
+        noModal={noModal}
         value={value}
       />
     );
diff --git a/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.js b/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.js
index 2ddba140e..d8989ec61 100644
--- a/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.js
+++ b/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.js
@@ -11,6 +11,7 @@ import { replyCompose } from 'flavours/glitch/actions/compose';
 import { reblog, favourite, unreblog, unfavourite } from 'flavours/glitch/actions/interactions';
 import { makeGetStatus } from 'flavours/glitch/selectors';
 import { openModal } from 'flavours/glitch/actions/modal';
+import { initBoostModal } from 'flavours/glitch/actions/boosts';
 
 const messages = defineMessages({
   reply: { id: 'status.reply', defaultMessage: 'Reply' },
@@ -82,9 +83,9 @@ class Footer extends ImmutablePureComponent {
     }
   };
 
-  _performReblog = () => {
+  _performReblog = (privacy) => {
     const { dispatch, status } = this.props;
-    dispatch(reblog(status));
+    dispatch(reblog(status, privacy));
   }
 
   handleReblogClick = e => {
@@ -95,7 +96,7 @@ class Footer extends ImmutablePureComponent {
     } else if ((e && e.shiftKey) || !boostModal) {
       this._performReblog();
     } else {
-      dispatch(openModal('BOOST', { status, onReblog: this._performReblog }));
+      dispatch(initBoostModal({ status, onReblog: this._performReblog }));
     }
   };
 
diff --git a/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js b/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js
index 9d11f37e0..40e186569 100644
--- a/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js
+++ b/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js
@@ -24,6 +24,7 @@ import {
 import { initMuteModal } from 'flavours/glitch/actions/mutes';
 import { initBlockModal } from 'flavours/glitch/actions/blocks';
 import { initReport } from 'flavours/glitch/actions/reports';
+import { initBoostModal } from 'flavours/glitch/actions/boosts';
 import { openModal } from 'flavours/glitch/actions/modal';
 import { defineMessages, injectIntl } from 'react-intl';
 import { boostModal, deleteModal } from 'flavours/glitch/util/initial_state';
@@ -67,8 +68,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
     });
   },
 
-  onModalReblog (status) {
-    dispatch(reblog(status));
+  onModalReblog (status, privacy) {
+    dispatch(reblog(status, privacy));
   },
 
   onReblog (status, e) {
@@ -78,7 +79,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
       if (e.shiftKey || !boostModal) {
         this.onModalReblog(status);
       } else {
-        dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog }));
+        dispatch(initBoostModal({ status, onReblog: this.onModalReblog }));
       }
     }
   },
diff --git a/app/javascript/flavours/glitch/features/status/index.js b/app/javascript/flavours/glitch/features/status/index.js
index b330adf3f..21e441407 100644
--- a/app/javascript/flavours/glitch/features/status/index.js
+++ b/app/javascript/flavours/glitch/features/status/index.js
@@ -30,6 +30,7 @@ import { muteStatus, unmuteStatus, deleteStatus } from 'flavours/glitch/actions/
 import { initMuteModal } from 'flavours/glitch/actions/mutes';
 import { initBlockModal } from 'flavours/glitch/actions/blocks';
 import { initReport } from 'flavours/glitch/actions/reports';
+import { initBoostModal } from 'flavours/glitch/actions/boosts';
 import { makeGetStatus } from 'flavours/glitch/selectors';
 import { ScrollContainer } from 'react-router-scroll-4';
 import ColumnBackButton from 'flavours/glitch/components/column_back_button';
@@ -262,13 +263,13 @@ class Status extends ImmutablePureComponent {
     }
   }
 
-  handleModalReblog = (status) => {
+  handleModalReblog = (status, privacy) => {
     const { dispatch } = this.props;
 
     if (status.get('reblogged')) {
       dispatch(unreblog(status));
     } else {
-      dispatch(reblog(status));
+      dispatch(reblog(status, privacy));
     }
   }
 
@@ -276,11 +277,11 @@ class Status extends ImmutablePureComponent {
     const { settings, dispatch } = this.props;
 
     if (settings.get('confirm_boost_missing_media_description') && status.get('media_attachments').some(item => !item.get('description')) && !status.get('reblogged')) {
-      dispatch(openModal('BOOST', { status, onReblog: this.handleModalReblog, missingMediaDescription: true }));
+      dispatch(initBoostModal({ status, onReblog: this.handleModalReblog, missingMediaDescription: true }));
     } else if ((e && e.shiftKey) || !boostModal) {
       this.handleModalReblog(status);
     } else {
-      dispatch(openModal('BOOST', { status, onReblog: this.handleModalReblog }));
+      dispatch(initBoostModal({ status, onReblog: this.handleModalReblog }));
     }
   }
 
diff --git a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
index 12ad426c8..c4af25599 100644
--- a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
@@ -1,4 +1,5 @@
 import React from 'react';
+import { connect } from 'react-redux';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
@@ -10,7 +11,9 @@ import DisplayName from 'flavours/glitch/components/display_name';
 import AttachmentList from 'flavours/glitch/components/attachment_list';
 import Icon from 'flavours/glitch/components/icon';
 import ImmutablePureComponent from 'react-immutable-pure-component';
+import PrivacyDropdown from 'flavours/glitch/features/compose/components/privacy_dropdown';
 import classNames from 'classnames';
+import { changeBoostPrivacy } from 'flavours/glitch/actions/boosts';
 
 const messages = defineMessages({
   cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
@@ -21,7 +24,22 @@ const messages = defineMessages({
   direct_short: { id: 'privacy.direct.short', defaultMessage: 'Direct' },
 });
 
-export default @injectIntl
+const mapStateToProps = state => {
+  return {
+    privacy: state.getIn(['boosts', 'new', 'privacy']),
+  };
+};
+
+const mapDispatchToProps = dispatch => {
+  return {
+    onChangeBoostPrivacy(value) {
+      dispatch(changeBoostPrivacy(value));
+    },
+  };
+};
+
+export default @connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
 class BoostModal extends ImmutablePureComponent {
 
   static contextTypes = {
@@ -41,7 +59,7 @@ class BoostModal extends ImmutablePureComponent {
   }
 
   handleReblog = () => {
-    this.props.onReblog(this.props.status);
+    this.props.onReblog(this.props.status, this.props.privacy);
     this.props.onClose();
   }
 
@@ -55,12 +73,16 @@ class BoostModal extends ImmutablePureComponent {
     }
   }
 
+  _findContainer = () => {
+    return document.getElementsByClassName('modal-root__container')[0];
+  };
+
   setRef = (c) => {
     this.button = c;
   }
 
   render () {
-    const { status, missingMediaDescription, intl } = this.props;
+    const { status, missingMediaDescription, privacy, intl } = this.props;
     const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog;
 
     const visibilityIconInfo = {
@@ -111,6 +133,15 @@ class BoostModal extends ImmutablePureComponent {
                 <FormattedMessage id='boost_modal.combo' defaultMessage='You can press {combo} to skip this next time' values={{ combo: <span>Shift + <Icon id='retweet' /></span> }} />
             }
           </div>
+
+          {status.get('visibility') !== 'private' && !status.get('reblogged') && (
+            <PrivacyDropdown
+              noDirect
+              value={privacy}
+              container={this._findContainer}
+              onChange={this.props.onChangeBoostPrivacy}
+            />
+          )}
           <Button text={intl.formatMessage(buttonText)} onClick={this.handleReblog} ref={this.setRef} />
         </div>
       </div>