]>
cat aescling's git repositories - mastodon.git/blob - app/javascript/mastodon/features/compose/components/privacy_dropdown.js
1 import React
from 'react';
2 import PropTypes
from 'prop-types';
3 import { injectIntl
, defineMessages
} from 'react-intl';
4 import IconButton
from '../../../components/icon_button';
5 import detectPassiveEvents
from 'detect-passive-events';
7 const messages
= defineMessages({
8 public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
9 public_long: { id: 'privacy.public.long', defaultMessage: 'Post to public timelines' },
10 unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
11 unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Do not show in public timelines' },
12 private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
13 private_long: { id: 'privacy.private.long', defaultMessage: 'Post to followers only' },
14 direct_short: { id: 'privacy.direct.short', defaultMessage: 'Direct' },
15 direct_long: { id: 'privacy.direct.long', defaultMessage: 'Post to mentioned users only' },
16 change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' },
25 export default class PrivacyDropdown
extends React
.PureComponent
{
28 isUserTouching: PropTypes
.func
,
29 isModalOpen: PropTypes
.bool
.isRequired
,
30 onModalOpen: PropTypes
.func
,
31 onModalClose: PropTypes
.func
,
32 value: PropTypes
.string
.isRequired
,
33 onChange: PropTypes
.func
.isRequired
,
34 intl: PropTypes
.object
.isRequired
,
41 handleToggle
= () => {
42 if (this.props
.isUserTouching()) {
43 if (this.state
.open
) {
44 this.props
.onModalClose();
46 this.props
.onModalOpen({
47 actions: this.options
.map(option
=> ({ ...option
, active: option
.value
=== this.props
.value
})),
48 onClick: this.handleModalActionClick
,
52 this.setState({ open: !this.state
.open
});
56 handleModalActionClick
= (e
) => {
58 const { value
} = this.options
[e
.currentTarget
.getAttribute('data-index')];
59 this.props
.onModalClose();
60 this.props
.onChange(value
);
63 handleClick
= (e
) => {
64 if (e
.key
=== 'Escape') {
65 this.setState({ open: false });
66 } else if (!e
.key
|| e
.key
=== 'Enter') {
67 const value
= e
.currentTarget
.getAttribute('data-index');
69 this.setState({ open: false });
70 this.props
.onChange(value
);
74 onGlobalClick
= (e
) => {
75 if (e
.target
!== this.node
&& !this.node
.contains(e
.target
) && this.state
.open
) {
76 this.setState({ open: false });
80 componentWillMount () {
81 const { intl: { formatMessage
} } = this.props
;
84 { icon: 'globe', value: 'public', text: formatMessage(messages
.public_short
), meta: formatMessage(messages
.public_long
) },
85 { icon: 'unlock-alt', value: 'unlisted', text: formatMessage(messages
.unlisted_short
), meta: formatMessage(messages
.unlisted_long
) },
86 { icon: 'lock', value: 'private', text: formatMessage(messages
.private_short
), meta: formatMessage(messages
.private_long
) },
87 { icon: 'envelope', value: 'direct', text: formatMessage(messages
.direct_short
), meta: formatMessage(messages
.direct_long
) },
91 componentDidMount () {
92 window
.addEventListener('click', this.onGlobalClick
);
93 window
.addEventListener('touchstart', this.onGlobalClick
, detectPassiveEvents
.hasSupport
? { passive: true } : false);
96 componentWillUnmount () {
97 window
.removeEventListener('click', this.onGlobalClick
);
98 window
.removeEventListener('touchstart', this.onGlobalClick
, detectPassiveEvents
.hasSupport
? { passive: true } : false);
106 const { value
, intl
} = this.props
;
107 const { open
} = this.state
;
109 const valueOption
= this.options
.find(item
=> item
.value
=== value
);
112 <div ref
={this.setRef
} className
={`privacy-dropdown ${open ? 'active' : ''}`}>
113 <div className
='privacy-dropdown__value'><IconButton className
='privacy-dropdown__value-icon' icon
={valueOption
.icon
} title
={intl
.formatMessage(messages
.change_privacy
)} size
={18} expanded
={open
} active
={open
} inverted onClick
={this.handleToggle
} style
={iconStyle
} /></div>
114 <div className
='privacy-dropdown__dropdown'>
115 {open
&& this.options
.map(item
=>
116 <div role
='button' tabIndex
='0' key
={item
.value
} data
-index
={item
.value
} onKeyDown
={this.handleClick
} onClick
={this.handleClick
} className
={`privacy-dropdown__option ${item.value === value ? 'active' : ''}`}>
117 <div className
='privacy-dropdown__option__icon'><i className
={`fa fa-fw fa-${item.icon}`} /></div>
118 <div className
='privacy-dropdown__option__content'>
119 <strong
>{item
.text
}</strong
>
This page took 0.106368 seconds and 5 git commands to generate.