diff --git a/app/javascript/flavours/glitch/components/dropdown_menu.js b/app/javascript/flavours/glitch/components/dropdown_menu.js
index 023fecb9ab2..a4d0dfc50d6 100644
--- a/app/javascript/flavours/glitch/components/dropdown_menu.js
+++ b/app/javascript/flavours/glitch/components/dropdown_menu.js
@@ -116,7 +116,7 @@ class DropdownMenu extends React.PureComponent {
if (typeof action === 'function') {
e.preventDefault();
- action();
+ action(e);
} else if (to) {
e.preventDefault();
this.context.router.history.push(to);
@@ -128,11 +128,11 @@ class DropdownMenu extends React.PureComponent {
return
+
@@ -236,7 +236,8 @@ export default class Dropdown extends React.PureComponent {
}
}
- handleItemClick = (i, e) => {
+ handleItemClick = e => {
+ const i = Number(e.currentTarget.getAttribute('data-index'));
const { action, to } = this.props.items[i];
this.handleClose();
diff --git a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js
index 1c0385b740b..0c4a2b50ffa 100644
--- a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js
+++ b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js
@@ -14,15 +14,11 @@ const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({
onOpen(id, onItemClick, dropdownPlacement, keyboard) {
dispatch(isUserTouching() ? openModal('ACTIONS', {
status,
- actions: items.map(
- (item, i) => item ? {
- ...item,
- name: `${item.text}-${i}`,
- onClick: item.action ? ((e) => { return onItemClick(i, e) }) : null,
- } : null
- ),
+ actions: items,
+ onClick: onItemClick,
}) : openDropdownMenu(id, dropdownPlacement, keyboard, scrollKey));
},
+
onClose(id) {
dispatch(closeModal('ACTIONS'));
dispatch(closeDropdownMenu(id));
diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown.js b/app/javascript/flavours/glitch/features/compose/components/dropdown.js
index abf7cbba141..9f70d6b794e 100644
--- a/app/javascript/flavours/glitch/features/compose/components/dropdown.js
+++ b/app/javascript/flavours/glitch/features/compose/components/dropdown.js
@@ -21,22 +21,25 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
icon: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.shape({
icon: PropTypes.string,
- meta: PropTypes.node,
+ meta: PropTypes.string,
name: PropTypes.string.isRequired,
- on: PropTypes.bool,
- text: PropTypes.node,
+ text: PropTypes.string,
})).isRequired,
onModalOpen: PropTypes.func,
onModalClose: PropTypes.func,
title: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func,
- noModal: PropTypes.bool,
container: PropTypes.func,
+ renderItemContents: PropTypes.func,
+ closeOnChange: PropTypes.bool,
+ };
+
+ static defaultProps = {
+ closeOnChange: true,
};
state = {
- needsModalUpdate: false,
open: false,
openedViaKeyboard: undefined,
placement: 'bottom',
@@ -44,10 +47,10 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
// Toggles opening and closing the dropdown.
handleToggle = ({ target, type }) => {
- const { onModalOpen, noModal } = this.props;
+ const { onModalOpen } = this.props;
const { open } = this.state;
- if (!noModal && isUserTouching()) {
+ if (isUserTouching()) {
if (this.state.open) {
this.props.onModalClose();
} else {
@@ -107,9 +110,25 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
this.setState({ open: false });
}
+ handleItemClick = (e) => {
+ const {
+ items,
+ onChange,
+ onModalClose,
+ closeOnChange,
+ } = this.props;
+
+ const i = Number(e.currentTarget.getAttribute('data-index'));
+
+ const { name } = items[i];
+
+ e.preventDefault(); // Prevents focus from changing
+ if (closeOnChange) onModalClose();
+ onChange(name);
+ };
+
// Creates an action modal object.
handleMakeModal = () => {
- const component = this;
const {
items,
onChange,
@@ -125,6 +144,8 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
// The object.
return {
+ renderItemContents: this.props.renderItemContents,
+ onClick: this.handleItemClick,
actions: items.map(
({
name,
@@ -133,48 +154,11 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
...rest,
active: value && name === value,
name,
- onClick (e) {
- e.preventDefault(); // Prevents focus from changing
- onModalClose();
- onChange(name);
- },
- onPassiveClick (e) {
- e.preventDefault(); // Prevents focus from changing
- onChange(name);
- component.setState({ needsModalUpdate: true });
- },
})
),
};
}
- // If our modal is open and our props update, we need to also update
- // the modal.
- handleUpdate = () => {
- const { onModalOpen } = this.props;
- const { needsModalUpdate } = this.state;
-
- // Gets our modal object.
- const modal = this.handleMakeModal();
-
- // Reopens the modal with the new object.
- if (needsModalUpdate && modal && onModalOpen) {
- onModalOpen(modal);
- }
- }
-
- // Updates our modal as necessary.
- componentDidUpdate (prevProps) {
- const { items } = this.props;
- const { needsModalUpdate } = this.state;
- if (needsModalUpdate && items.find(
- (item, i) => item.on !== prevProps.items[i].on
- )) {
- this.handleUpdate();
- this.setState({ needsModalUpdate: false });
- }
- }
-
// Rendering.
render () {
const {
@@ -186,6 +170,8 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
onChange,
value,
container,
+ renderItemContents,
+ closeOnChange,
} = this.props;
const { open, placement } = this.state;
const computedClass = classNames('composer--options--dropdown', {
@@ -226,10 +212,12 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
>
diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js
index bee06e64c7f..0649fe1caaa 100644
--- a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js
+++ b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js
@@ -2,7 +2,6 @@
import PropTypes from 'prop-types';
import React from 'react';
import spring from 'react-motion/lib/spring';
-import Toggle from 'react-toggle';
import ImmutablePureComponent from 'react-immutable-pure-component';
import classNames from 'classnames';
@@ -28,18 +27,20 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
icon: PropTypes.string,
meta: PropTypes.node,
name: PropTypes.string.isRequired,
- on: PropTypes.bool,
text: PropTypes.node,
})),
onChange: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
style: PropTypes.object,
value: PropTypes.string,
+ renderItemContents: PropTypes.func,
openedViaKeyboard: PropTypes.bool,
+ closeOnChange: PropTypes.bool,
};
static defaultProps = {
style: {},
+ closeOnChange: true,
};
state = {
@@ -77,16 +78,19 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
document.removeEventListener('touchend', this.handleDocumentClick, withPassive);
}
- handleClick = (name, e) => {
+ handleClick = (e) => {
+ const i = Number(e.currentTarget.getAttribute('data-index'));
+
const {
onChange,
onClose,
+ closeOnChange,
items,
} = this.props;
- const { on } = this.props.items.find(item => item.name === name);
+ const { name } = this.props.items[i];
e.preventDefault(); // Prevents change in focus on click
- if ((on === null || typeof on === 'undefined')) {
+ if (closeOnChange) {
onClose();
}
onChange(name);
@@ -101,11 +105,9 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
}
}
- handleKeyDown = (name, e) => {
+ handleKeyDown = (e) => {
+ const index = Number(e.currentTarget.getAttribute('data-index'));
const { items } = this.props;
- const index = items.findIndex(item => {
- return (item.name === name);
- });
let element = null;
switch(e.key) {
@@ -139,7 +141,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
if (element) {
element.focus();
- this.handleChange(element.getAttribute('data-index'));
+ this.handleChange(this.props.items[Number(element.getAttribute('data-index'))].name);
e.preventDefault();
e.stopPropagation();
}
@@ -149,44 +151,40 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
this.focusedItem = c;
}
- renderItem = (item) => {
- const { name, icon, meta, on, text } = item;
+ renderItem = (item, i) => {
+ const { name, icon, meta, text } = item;
const active = (name === (this.props.value || this.state.value));
- const computedClass = classNames('composer--options--dropdown--content--item', {
- active,
- lengthy: meta,
- 'toggled-off': !on && on !== null && typeof on !== 'undefined',
- 'toggled-on': on,
- 'with-icon': icon,
- });
+ const computedClass = classNames('composer--options--dropdown--content--item', { active });
- let prefix = null;
+ let contents = this.props.renderItemContents && this.props.renderItemContents(item, i);
- if (on !== null && typeof on !== 'undefined') {
- prefix =
;
- } else if (icon) {
- prefix =
+ if (!contents) {
+ contents = (
+
+ {icon && }
+
+
+ {text}
+ {meta}
+
+
+ );
}
return (
- {prefix}
-
-
- {text}
- {meta}
-
+ {contents}
);
}
@@ -229,7 +227,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
transform: mounted ? `scale(${scaleX}, ${scaleY})` : null,
}}
>
- {!!items && items.map(item => this.renderItem(item))}
+ {!!items && items.map((item, i) => this.renderItem(item, i))}
)}
diff --git a/app/javascript/flavours/glitch/features/compose/components/options.js b/app/javascript/flavours/glitch/features/compose/components/options.js
index f9212bbaeba..085da18ea4e 100644
--- a/app/javascript/flavours/glitch/features/compose/components/options.js
+++ b/app/javascript/flavours/glitch/features/compose/components/options.js
@@ -2,8 +2,10 @@
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
-import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, injectIntl } from 'react-intl';
import spring from 'react-motion/lib/spring';
+import Toggle from 'react-toggle';
+import { connect } from 'react-redux';
// Components.
import IconButton from 'flavours/glitch/components/icon_button';
@@ -80,6 +82,36 @@ const messages = defineMessages({
},
});
+@connect((state, { name }) => ({ checked: state.getIn(['compose', 'advanced_options', name]) }))
+class ToggleOption extends ImmutablePureComponent {
+
+ static propTypes = {
+ name: PropTypes.string.isRequired,
+ checked: PropTypes.bool,
+ onChangeAdvancedOption: PropTypes.func.isRequired,
+ };
+
+ handleChange = () => {
+ this.props.onChangeAdvancedOption(this.props.name);
+ };
+
+ render() {
+ const { meta, text, checked } = this.props;
+
+ return (
+