import PropTypes from 'prop-types'; import { PureComponent } from 'react'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import { Helmet } from 'react-helmet'; import { withRouter } from 'react-router-dom'; import { List as ImmutableList, Map as ImmutableMap } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; import Select, { NonceProvider } from 'react-select'; import Toggle from 'react-toggle'; import DeleteIcon from '@/material-icons/400-24px/delete.svg?react'; import DomainIcon from '@/material-icons/400-24px/dns.svg?react'; import EditIcon from '@/material-icons/400-24px/edit.svg?react'; import HashtagIcon from '@/material-icons/400-24px/tag.svg?react'; import KeywordIcon from '@/material-icons/400-24px/title.svg?react'; import AntennaIcon from '@/material-icons/400-24px/wifi.svg?react'; import { fetchAntenna, deleteAntenna, updateAntenna, addDomainToAntenna, removeDomainFromAntenna, addExcludeDomainToAntenna, removeExcludeDomainFromAntenna, fetchAntennaDomains, fetchAntennaKeywords, removeKeywordFromAntenna, addKeywordToAntenna, removeExcludeKeywordFromAntenna, addExcludeKeywordToAntenna, fetchAntennaTags, removeTagFromAntenna, addTagToAntenna, removeExcludeTagFromAntenna, addExcludeTagToAntenna, } from 'mastodon/actions/antennas'; import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns'; import { fetchLists } from 'mastodon/actions/lists'; import { openModal } from 'mastodon/actions/modal'; import { Button } from 'mastodon/components/button'; import Column from 'mastodon/components/column'; import ColumnHeader from 'mastodon/components/column_header'; import { Icon } from 'mastodon/components/icon'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error'; import { enableLocalTimeline } from 'mastodon/initial_state'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import RadioPanel from './components/radio_panel'; import TextList from './components/text_list'; const messages = defineMessages({ deleteMessage: { id: 'confirmations.delete_antenna.message', defaultMessage: 'Are you sure you want to permanently delete this antenna?' }, deleteConfirm: { id: 'confirmations.delete_antenna.confirm', defaultMessage: 'Delete' }, editAccounts: { id: 'antennas.edit_accounts', defaultMessage: 'Edit accounts' }, noOptions: { id: 'antennas.select.no_options_message', defaultMessage: 'Empty lists' }, placeholder: { id: 'antennas.select.placeholder', defaultMessage: 'Select list' }, addDomainLabel: { id: 'antennas.add_domain_placeholder', defaultMessage: 'New domain' }, addKeywordLabel: { id: 'antennas.add_keyword_placeholder', defaultMessage: 'New keyword' }, addTagLabel: { id: 'antennas.add_tag_placeholder', defaultMessage: 'New tag' }, addDomainTitle: { id: 'antennas.add_domain', defaultMessage: 'Add domain' }, addKeywordTitle: { id: 'antennas.add_keyword', defaultMessage: 'Add keyword' }, addTagTitle: { id: 'antennas.add_tag', defaultMessage: 'Add tag' }, accounts: { id: 'antennas.accounts', defaultMessage: '{count} accounts' }, domains: { id: 'antennas.domains', defaultMessage: '{count} domains' }, tags: { id: 'antennas.tags', defaultMessage: '{count} tags' }, keywords: { id: 'antennas.keywords', defaultMessage: '{count} keywords' }, setHome: { id: 'antennas.select.set_home', defaultMessage: 'Set home' }, }); const mapStateToProps = (state, props) => ({ antenna: state.getIn(['antennas', props.params.id]), lists: state.get('lists'), domains: state.getIn(['antennas', props.params.id, 'domains']) || ImmutableMap(), keywords: state.getIn(['antennas', props.params.id, 'keywords']) || ImmutableMap(), tags: state.getIn(['antennas', props.params.id, 'tags']) || ImmutableMap(), }); class AntennaSetting extends PureComponent { static propTypes = { params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, columnId: PropTypes.string, multiColumn: PropTypes.bool, antenna: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]), lists: ImmutablePropTypes.map, domains: ImmutablePropTypes.map, keywords: ImmutablePropTypes.map, tags: ImmutablePropTypes.map, intl: PropTypes.object.isRequired, ...WithRouterPropTypes, }; state = { domainName: '', excludeDomainName: '', keywordName: '', excludeKeywordName: '', tagName: '', excludeTagName: '', rangeRadioValue: null, contentRadioValue: null, }; handlePin = () => { const { columnId, dispatch } = this.props; if (columnId) { dispatch(removeColumn(columnId)); } else { dispatch(addColumn('ANTENNA', { id: this.props.params.id })); this.props.history.push('/'); } }; handleMove = (dir) => { const { columnId, dispatch } = this.props; dispatch(moveColumn(columnId, dir)); }; handleHeaderClick = () => { this.column.scrollTop(); }; componentDidMount () { const { dispatch } = this.props; const { id } = this.props.params; dispatch(fetchAntenna(id)); dispatch(fetchAntennaDomains(id)); dispatch(fetchAntennaKeywords(id)); dispatch(fetchAntennaTags(id)); dispatch(fetchLists()); } UNSAFE_componentWillReceiveProps (nextProps) { const { dispatch } = this.props; const { id } = nextProps.params; if (id !== this.props.params.id) { dispatch(fetchAntenna(id)); dispatch(fetchAntennaKeywords(id)); dispatch(fetchAntennaDomains(id)); dispatch(fetchAntennaKeywords(id)); dispatch(fetchAntennaTags(id)); dispatch(fetchLists()); } } setRef = c => { this.column = c; }; handleEditClick = () => { this.props.dispatch(openModal({ modalType: 'ANTENNA_EDITOR', modalProps: { antennaId: this.props.params.id, isExclude: false }, })); }; handleExcludeEditClick = () => { this.props.dispatch(openModal({ modalType: 'ANTENNA_EDITOR', modalProps: { antennaId: this.props.params.id, isExclude: true }, })); }; handleEditAntennaClick = () => { window.open(`/antennas/${this.props.params.id}/edit`, '_blank'); }; handleDeleteClick = () => { const { dispatch, columnId, intl } = this.props; const { id } = this.props.params; dispatch(openModal({ modalType: 'CONFIRM', modalProps: { message: intl.formatMessage(messages.deleteMessage), confirm: intl.formatMessage(messages.deleteConfirm), onConfirm: () => { dispatch(deleteAntenna(id)); if (columnId) { dispatch(removeColumn(columnId)); } else { this.props.history.push('/antennasw'); } }, }, })); }; handleTimelineClick = () => { this.props.history.push(`/antennast/${this.props.params.id}`); }; onStlToggle = ({ target }) => { const { dispatch } = this.props; const { id } = this.props.params; dispatch(updateAntenna(id, undefined, false, undefined, target.checked, undefined, undefined, undefined, undefined)); }; onLtlToggle = ({ target }) => { const { dispatch } = this.props; const { id } = this.props.params; dispatch(updateAntenna(id, undefined, false, undefined, undefined, target.checked, undefined, undefined, undefined)); }; onMediaOnlyToggle = ({ target }) => { const { dispatch } = this.props; const { id } = this.props.params; dispatch(updateAntenna(id, undefined, false, undefined, undefined, undefined, target.checked, undefined, undefined)); }; onIgnoreReblogToggle = ({ target }) => { const { dispatch } = this.props; const { id } = this.props.params; dispatch(updateAntenna(id, undefined, false, undefined, undefined, undefined, undefined, target.checked, undefined)); }; onNoInsertFeedsToggle = ({ target }) => { const { dispatch } = this.props; const { id } = this.props.params; dispatch(updateAntenna(id, undefined, false, undefined, undefined, undefined, undefined, undefined, target.checked)); }; onSelect = value => { const { dispatch } = this.props; const { id } = this.props.params; dispatch(updateAntenna(id, undefined, false, value.value, undefined, undefined, undefined, undefined, undefined)); }; onHomeSelect = () => this.onSelect({ value: '0' }); noOptionsMessage = () => this.props.intl.formatMessage(messages.noOptions); onRangeRadioChanged = (value) => this.setState({ rangeRadioValue: value }); onContentRadioChanged = (value) => this.setState({ contentRadioValue: value }); onDomainNameChanged = (value) => this.setState({ domainName: value }); onDomainAdd = () => { this.props.dispatch(addDomainToAntenna(this.props.params.id, this.state.domainName)); this.setState({ domainName: '' }); }; onDomainRemove = (value) => this.props.dispatch(removeDomainFromAntenna(this.props.params.id, value)); onKeywordNameChanged = (value) => this.setState({ keywordName: value }); onKeywordAdd = () => { this.props.dispatch(addKeywordToAntenna(this.props.params.id, this.state.keywordName)); this.setState({ keywordName: '' }); }; onKeywordRemove = (value) => this.props.dispatch(removeKeywordFromAntenna(this.props.params.id, value)); onTagNameChanged = (value) => this.setState({ tagName: value }); onTagAdd = () => { this.props.dispatch(addTagToAntenna(this.props.params.id, this.state.tagName)); this.setState({ tagName: '' }); }; onTagRemove = (value) => this.props.dispatch(removeTagFromAntenna(this.props.params.id, value)); onExcludeDomainNameChanged = (value) => this.setState({ excludeDomainName: value }); onExcludeDomainAdd = () => { this.props.dispatch(addExcludeDomainToAntenna(this.props.params.id, this.state.excludeDomainName)); this.setState({ excludeDomainName: '' }); }; onExcludeDomainRemove = (value) => this.props.dispatch(removeExcludeDomainFromAntenna(this.props.params.id, value)); onExcludeKeywordNameChanged = (value) => this.setState({ excludeKeywordName: value }); onExcludeKeywordAdd = () => { this.props.dispatch(addExcludeKeywordToAntenna(this.props.params.id, this.state.excludeKeywordName)); this.setState({ excludeKeywordName: '' }); }; onExcludeKeywordRemove = (value) => this.props.dispatch(removeExcludeKeywordFromAntenna(this.props.params.id, value)); onExcludeTagNameChanged = (value) => this.setState({ excludeTagName: value }); onExcludeTagAdd = () => { this.props.dispatch(addExcludeTagToAntenna(this.props.params.id, this.state.excludeTagName)); this.setState({ excludeTagName: '' }); }; onExcludeTagRemove = (value) => this.props.dispatch(removeExcludeTagFromAntenna(this.props.params.id, value)); render () { const { columnId, multiColumn, antenna, lists, domains, keywords, tags, intl } = this.props; const { id } = this.props.params; const pinned = !!columnId; const title = antenna ? antenna.get('title') : id; const isStl = antenna ? antenna.get('stl') : undefined; const isLtl = antenna ? antenna.get('ltl') : undefined; const isMediaOnly = antenna ? antenna.get('with_media_only') : undefined; const isIgnoreReblog = antenna ? antenna.get('ignore_reblog') : undefined; const isInsertFeeds = antenna ? antenna.get('insert_feeds') : undefined; if (typeof antenna === 'undefined') { return (
); } else if (antenna === false) { return ( ); } let columnSettings; if (!isStl && !isLtl) { columnSettings = ( <>
); } let stlAlert; if (isStl) { stlAlert = (

); } else if (isLtl) { stlAlert = (

); } const rangeRadioValues = ImmutableList([ ImmutableMap({ value: 'accounts', label: intl.formatMessage(messages.accounts, { count: antenna.get('accounts_count') }) }), ImmutableMap({ value: 'domains', label: intl.formatMessage(messages.domains, { count: antenna.get('domains_count') }) }), ]); const rangeRadioValue = ImmutableMap({ value: this.state.rangeRadioValue || (antenna.get('domains_count') > 0 ? 'domains' : 'accounts') }); const rangeRadioAlert = antenna.get(rangeRadioValue.get('value') === 'accounts' ? 'domains_count' : 'accounts_count') > 0; const contentRadioValues = ImmutableList([ ImmutableMap({ value: 'keywords', label: intl.formatMessage(messages.keywords, { count: antenna.get('keywords_count') }) }), ImmutableMap({ value: 'tags', label: intl.formatMessage(messages.tags, { count: antenna.get('tags_count') }) }), ]); const contentRadioValue = ImmutableMap({ value: this.state.contentRadioValue || (antenna.get('tags_count') > 0 ? 'tags' : 'keywords') }); const contentRadioAlert = antenna.get(contentRadioValue.get('value') === 'tags' ? 'keywords_count' : 'tags_count') > 0; const listOptions = lists.toArray().filter((list) => list.length >= 2 && list[1]).map((list) => { return { value: list[1].get('id'), label: list[1].get('title') }; }); return (
{!isLtl && (enableLocalTimeline || isStl) && (
)} {!isStl && (enableLocalTimeline || isLtl) && (
)}
{columnSettings}
{stlAlert}
{isInsertFeeds && ( <> {antenna.get('list') ? (

) : (

)}