Fix searchability dropdown is not open

This commit is contained in:
KMY 2023-05-28 12:33:45 +09:00
parent 38104b3694
commit f7e6ed1ff1
4 changed files with 46 additions and 21 deletions

View file

@ -1,16 +1,20 @@
import { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { injectIntl, defineMessages } from 'react-intl'; import { injectIntl, defineMessages } from 'react-intl';
import { IconButton } from '../../../components/icon_button';
import Overlay from 'react-overlays/Overlay';
import { supportsPassiveEvents } from 'detect-passive-events';
import classNames from 'classnames'; import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay';
import { IconButton } from '../../../components/icon_button';
const messages = defineMessages({ const messages = defineMessages({
add_expiration: { id: 'status.expiration.add', defaultMessage: 'Set status expiration' }, add_expiration: { id: 'status.expiration.add', defaultMessage: 'Set status expiration' },
}); });
const listenerOptions = supportsPassiveEvents ? { passive: true } : false; const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
class ExpirationDropdownMenu extends PureComponent { class ExpirationDropdownMenu extends PureComponent {
@ -25,6 +29,7 @@ class ExpirationDropdownMenu extends PureComponent {
handleDocumentClick = e => { handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) { if (this.node && !this.node.contains(e.target)) {
this.props.onClose(); this.props.onClose();
e.stopPropagation();
} }
}; };
@ -82,13 +87,13 @@ class ExpirationDropdownMenu extends PureComponent {
}; };
componentDidMount () { componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem) this.focusedItem.focus({ preventScroll: true }); if (this.focusedItem) this.focusedItem.focus({ preventScroll: true });
} }
componentWillUnmount () { componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, false); document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
} }

View file

@ -1,11 +1,16 @@
import { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { injectIntl, defineMessages } from 'react-intl'; import { injectIntl, defineMessages } from 'react-intl';
import { IconButton } from '../../../components/icon_button';
import Overlay from 'react-overlays/Overlay';
import { supportsPassiveEvents } from 'detect-passive-events';
import classNames from 'classnames'; import classNames from 'classnames';
import { Icon } from 'mastodon/components/icon';
import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay';
import { Icon } from 'mastodon/components/icon';
import { IconButton } from '../../../components/icon_button';
const messages = defineMessages({ const messages = defineMessages({
public_short: { id: 'searchability.public.short', defaultMessage: 'Public' }, public_short: { id: 'searchability.public.short', defaultMessage: 'Public' },
@ -19,7 +24,7 @@ const messages = defineMessages({
change_searchability: { id: 'searchability.change', defaultMessage: 'Set status searchability' }, change_searchability: { id: 'searchability.change', defaultMessage: 'Set status searchability' },
}); });
const listenerOptions = supportsPassiveEvents ? { passive: true } : false; const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
class SearchabilityDropdownMenu extends PureComponent { class SearchabilityDropdownMenu extends PureComponent {
@ -34,6 +39,7 @@ class SearchabilityDropdownMenu extends PureComponent {
handleDocumentClick = e => { handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) { if (this.node && !this.node.contains(e.target)) {
this.props.onClose(); this.props.onClose();
e.stopPropagation();
} }
}; };
@ -91,13 +97,13 @@ class SearchabilityDropdownMenu extends PureComponent {
}; };
componentDidMount () { componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem) this.focusedItem.focus({ preventScroll: true }); if (this.focusedItem) this.focusedItem.focus({ preventScroll: true });
} }
componentWillUnmount () { componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, false); document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
} }

View file

@ -1,7 +1,8 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ExpirationDropdown from '../components/expiration_dropdown';
import { openModal, closeModal } from '../../../actions/modal'; import { openModal, closeModal } from '../../../actions/modal';
import { isUserTouching } from '../../../is_mobile'; import { isUserTouching } from '../../../is_mobile';
import ExpirationDropdown from '../components/expiration_dropdown';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
value: state.getIn(['compose', 'privacy']), value: state.getIn(['compose', 'privacy']),
@ -16,8 +17,14 @@ const mapDispatchToProps = (dispatch, { onPickExpiration }) => ({
}, },
isUserTouching, isUserTouching,
onModalOpen: props => dispatch(openModal('ACTIONS', props)), onModalOpen: props => dispatch(openModal({
onModalClose: () => dispatch(closeModal()), modalType: 'ACTIONS',
modalProps: props,
})),
onModalClose: () => dispatch(closeModal({
modalType: undefined,
ignoreFocus: false,
})),
}); });

View file

@ -1,8 +1,9 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import SearchabilityDropdown from '../components/searchability_dropdown';
import { changeComposeSearchability } from '../../../actions/compose'; import { changeComposeSearchability } from '../../../actions/compose';
import { openModal, closeModal } from '../../../actions/modal'; import { openModal, closeModal } from '../../../actions/modal';
import { isUserTouching } from '../../../is_mobile'; import { isUserTouching } from '../../../is_mobile';
import SearchabilityDropdown from '../components/searchability_dropdown';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
value: state.getIn(['compose', 'searchability']), value: state.getIn(['compose', 'searchability']),
@ -15,8 +16,14 @@ const mapDispatchToProps = dispatch => ({
}, },
isUserTouching, isUserTouching,
onModalOpen: props => dispatch(openModal('ACTIONS', props)), onModalOpen: props => dispatch(openModal({
onModalClose: () => dispatch(closeModal()), modalType: 'ACTIONS',
modalProps: props,
})),
onModalClose: () => dispatch(closeModal({
modalType: undefined,
ignoreFocus: false,
})),
}); });