{"version":3,"sources":["webpack:///app/javascript/opt/mastodon/app/javascript/flavours/glitch/features/hashtag_timeline/components/column_settings.js","webpack:///app/javascript/opt/mastodon/app/javascript/flavours/glitch/features/hashtag_timeline/containers/column_settings_container.js","webpack:///app/javascript/opt/mastodon/app/javascript/flavours/glitch/features/hashtag_timeline/index.js"],"names":["messages","defineMessages","placeholder","noOptions","ColumnSettings","injectIntl","React","PureComponent","state","open","this","hasTags","onSelect","mode","value","oldValue","tags","length","props","onChange","onToggle","setState","noOptionsMessage","intl","formatMessage","map","includes","settings","getIn","toJS","modeSelect","className","modeLabel","nonce","document","querySelector","content","cacheKey","isMulti","autoFocus","loadOptions","onLoad","classNamePrefix","name","id","defaultMessage","render","checked","settingPath","label","connect","columnId","columns","index","findIndex","c","get","api","params","q","type","then","response","data","hashtags","tag","dispatch","key","changeColumnParams","followHashtag","unfollowHashtag","HashtagTimeline","hasUnread","local","disconnects","handlePin","removeColumn","addColumn","title","additionalFor","push","values","additional","join","handleMove","dir","moveColumn","handleHeaderClick","column","scrollTop","setRef","handleLoadMore","maxId","expandHashtagTimeline","handleFollow","signedIn","context","identity","_subscribe","any","all","none","connectHashtagStream","status","filter","_unsubscribe","disconnect","_unload","clearTimeline","_load","fetchHashtag","componentDidMount","componentDidUpdate","prevProps","componentWillUnmount","multiColumn","pinned","followButton","following","classNames","onClick","disabled","active","fixedWidth","bindToDocument","ref","icon","onPin","onMove","extraButton","showBackButton","trackScroll","scrollKey","timelineId","onLoadMore","emptyMessage","Helmet","contextTypes","PropTypes","object"],"mappings":"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","file":"js/flavours/glitch/async/hashtag_timeline-e8e86b4622c6d8b211d8.chunk.js","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport ImmutablePropTypes from 'react-immutable-proptypes';\nimport { defineMessages, injectIntl, FormattedMessage } from 'react-intl';\nimport Toggle from 'react-toggle';\nimport AsyncSelect from 'react-select/async';\nimport { NonceProvider } from 'react-select';\nimport SettingToggle from '../../notifications/components/setting_toggle';\n\nconst messages = defineMessages({\n placeholder: { id: 'hashtag.column_settings.select.placeholder', defaultMessage: 'Enter hashtags…' },\n noOptions: { id: 'hashtag.column_settings.select.no_options_message', defaultMessage: 'No suggestions found' },\n});\n\nexport default @injectIntl\nclass ColumnSettings extends React.PureComponent {\n\n static propTypes = {\n settings: ImmutablePropTypes.map.isRequired,\n onChange: PropTypes.func.isRequired,\n onLoad: PropTypes.func.isRequired,\n intl: PropTypes.object.isRequired,\n };\n\n state = {\n open: this.hasTags(),\n };\n\n hasTags () {\n return ['all', 'any', 'none'].map(mode => this.tags(mode).length > 0).includes(true);\n }\n\n tags (mode) {\n let tags = this.props.settings.getIn(['tags', mode]) || [];\n\n if (tags.toJS) {\n return tags.toJS();\n } else {\n return tags;\n }\n };\n\n onSelect = mode => value => {\n const oldValue = this.tags(mode);\n\n // Prevent changes that add more than 4 tags, but allow removing\n // tags that were already added before\n if ((value.length > 4) && !(value < oldValue)) {\n return;\n }\n\n this.props.onChange(['tags', mode], value);\n };\n\n onToggle = () => {\n if (this.state.open && this.hasTags()) {\n this.props.onChange('tags', {});\n }\n\n this.setState({ open: !this.state.open });\n };\n\n noOptionsMessage = () => this.props.intl.formatMessage(messages.noOptions);\n\n modeSelect (mode) {\n return (\n <div className='column-settings__row'>\n <span className='column-settings__section'>\n {this.modeLabel(mode)}\n </span>\n\n <NonceProvider nonce={document.querySelector('meta[name=style-nonce]').content} cacheKey='tags'>\n <AsyncSelect\n isMulti\n autoFocus\n value={this.tags(mode)}\n onChange={this.onSelect(mode)}\n loadOptions={this.props.onLoad}\n className='column-select__container'\n classNamePrefix='column-select'\n name='tags'\n placeholder={this.props.intl.formatMessage(messages.placeholder)}\n noOptionsMessage={this.noOptionsMessage}\n />\n </NonceProvider>\n </div>\n );\n }\n\n modeLabel (mode) {\n switch(mode) {\n case 'any':\n return <FormattedMessage id='hashtag.column_settings.tag_mode.any' defaultMessage='Any of these' />;\n case 'all':\n return <FormattedMessage id='hashtag.column_settings.tag_mode.all' defaultMessage='All of these' />;\n case 'none':\n return <FormattedMessage id='hashtag.column_settings.tag_mode.none' defaultMessage='None of these' />;\n default:\n return '';\n }\n };\n\n render () {\n const { settings, onChange } = this.props;\n\n return (\n <div>\n <div className='column-settings__row'>\n <div className='setting-toggle'>\n <Toggle id='hashtag.column_settings.tag_toggle' onChange={this.onToggle} checked={this.state.open} />\n\n <span className='setting-toggle__label'>\n <FormattedMessage id='hashtag.column_settings.tag_toggle' defaultMessage='Include additional tags in this column' />\n </span>\n </div>\n </div>\n\n {this.state.open && (\n <div className='column-settings__hashtags'>\n {this.modeSelect('any')}\n {this.modeSelect('all')}\n {this.modeSelect('none')}\n </div>\n )}\n\n <div className='column-settings__row'>\n <SettingToggle settings={settings} settingPath={['local']} onChange={onChange} label={<FormattedMessage id='community.column_settings.local_only' defaultMessage='Local only' />} />\n </div>\n </div>\n );\n }\n\n}\n","import { connect } from 'react-redux';\nimport ColumnSettings from '../components/column_settings';\nimport { changeColumnParams } from 'flavours/glitch/actions/columns';\nimport api from 'flavours/glitch/api';\n\nconst mapStateToProps = (state, { columnId }) => {\n const columns = state.getIn(['settings', 'columns']);\n const index = columns.findIndex(c => c.get('uuid') === columnId);\n\n if (!(columnId && index >= 0)) {\n return {};\n }\n\n return {\n settings: columns.get(index).get('params'),\n onLoad (value) {\n return api(() => state).get('/api/v2/search', { params: { q: value, type: 'hashtags' } }).then(response => {\n return (response.data.hashtags || []).map((tag) => {\n return { value: tag.name, label: `#${tag.name}` };\n });\n });\n },\n };\n};\n\nconst mapDispatchToProps = (dispatch, { columnId }) => ({\n onChange (key, value) {\n dispatch(changeColumnParams(columnId, key, value));\n },\n});\n\nexport default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings);\n","import React from 'react';\nimport { connect } from 'react-redux';\nimport PropTypes from 'prop-types';\nimport StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container';\nimport Column from 'flavours/glitch/components/column';\nimport ColumnHeader from 'flavours/glitch/components/column_header';\nimport ImmutablePropTypes from 'react-immutable-proptypes';\nimport ColumnSettingsContainer from './containers/column_settings_container';\nimport { expandHashtagTimeline, clearTimeline } from 'flavours/glitch/actions/timelines';\nimport { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns';\nimport { connectHashtagStream } from 'flavours/glitch/actions/streaming';\nimport { injectIntl, FormattedMessage, defineMessages } from 'react-intl';\nimport { isEqual } from 'lodash';\nimport { fetchHashtag, followHashtag, unfollowHashtag } from 'flavours/glitch/actions/tags';\nimport Icon from 'flavours/glitch/components/icon';\nimport classNames from 'classnames';\nimport { Helmet } from 'react-helmet';\n\nconst messages = defineMessages({\n followHashtag: { id: 'hashtag.follow', defaultMessage: 'Follow hashtag' },\n unfollowHashtag: { id: 'hashtag.unfollow', defaultMessage: 'Unfollow hashtag' },\n});\n\nconst mapStateToProps = (state, props) => ({\n hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${props.params.local ? ':local' : ''}`, 'unread']) > 0,\n tag: state.getIn(['tags', props.params.id]),\n});\n\nexport default @connect(mapStateToProps)\n@injectIntl\nclass HashtagTimeline extends React.PureComponent {\n\n disconnects = [];\n\n static contextTypes = {\n identity: PropTypes.object,\n };\n\n static propTypes = {\n params: PropTypes.object.isRequired,\n columnId: PropTypes.string,\n dispatch: PropTypes.func.isRequired,\n hasUnread: PropTypes.bool,\n tag: ImmutablePropTypes.map,\n multiColumn: PropTypes.bool,\n intl: PropTypes.object,\n };\n\n handlePin = () => {\n const { columnId, dispatch } = this.props;\n\n if (columnId) {\n dispatch(removeColumn(columnId));\n } else {\n dispatch(addColumn('HASHTAG', { id: this.props.params.id }));\n }\n }\n\n title = () => {\n const { id } = this.props.params;\n const title = [id];\n\n if (this.additionalFor('any')) {\n title.push(' ', <FormattedMessage key='any' id='hashtag.column_header.tag_mode.any' values={{ additional: this.additionalFor('any') }} defaultMessage='or {additional}' />);\n }\n\n if (this.additionalFor('all')) {\n title.push(' ', <FormattedMessage key='all' id='hashtag.column_header.tag_mode.all' values={{ additional: this.additionalFor('all') }} defaultMessage='and {additional}' />);\n }\n\n if (this.additionalFor('none')) {\n title.push(' ', <FormattedMessage key='none' id='hashtag.column_header.tag_mode.none' values={{ additional: this.additionalFor('none') }} defaultMessage='without {additional}' />);\n }\n\n return title;\n }\n\n additionalFor = (mode) => {\n const { tags } = this.props.params;\n\n if (tags && (tags[mode] || []).length > 0) {\n return tags[mode].map(tag => tag.value).join('/');\n } else {\n return '';\n }\n }\n\n handleMove = (dir) => {\n const { columnId, dispatch } = this.props;\n dispatch(moveColumn(columnId, dir));\n }\n\n handleHeaderClick = () => {\n this.column.scrollTop();\n }\n\n _subscribe (dispatch, id, tags = {}, local) {\n const { signedIn } = this.context.identity;\n\n if (!signedIn) {\n return;\n }\n\n let any = (tags.any || []).map(tag => tag.value);\n let all = (tags.all || []).map(tag => tag.value);\n let none = (tags.none || []).map(tag => tag.value);\n\n [id, ...any].map(tag => {\n this.disconnects.push(dispatch(connectHashtagStream(id, tag, local, status => {\n let tags = status.tags.map(tag => tag.name);\n\n return all.filter(tag => tags.includes(tag)).length === all.length &&\n none.filter(tag => tags.includes(tag)).length === 0;\n })));\n });\n }\n\n _unsubscribe () {\n this.disconnects.map(disconnect => disconnect());\n this.disconnects = [];\n }\n\n _unload () {\n const { dispatch } = this.props;\n const { id, local } = this.props.params;\n\n this._unsubscribe();\n dispatch(clearTimeline(`hashtag:${id}${local ? ':local' : ''}`));\n }\n\n _load() {\n const { dispatch } = this.props;\n const { id, tags, local } = this.props.params;\n\n this._subscribe(dispatch, id, tags, local);\n dispatch(expandHashtagTimeline(id, { tags, local }));\n dispatch(fetchHashtag(id));\n }\n\n componentDidMount () {\n this._load();\n }\n\n componentDidUpdate (prevProps) {\n const { params } = this.props;\n const { id, tags, local } = prevProps.params;\n\n if (id !== params.id || !isEqual(tags, params.tags) || !isEqual(local, params.local)) {\n this._unload();\n this._load();\n }\n }\n\n componentWillUnmount () {\n this._unsubscribe();\n }\n\n setRef = c => {\n this.column = c;\n }\n\n handleLoadMore = maxId => {\n const { dispatch, params } = this.props;\n const { id, tags, local } = params;\n\n dispatch(expandHashtagTimeline(id, { maxId, tags, local }));\n }\n\n handleFollow = () => {\n const { dispatch, params, tag } = this.props;\n const { id } = params;\n const { signedIn } = this.context.identity;\n\n if (!signedIn) {\n return;\n }\n\n if (tag.get('following')) {\n dispatch(unfollowHashtag(id));\n } else {\n dispatch(followHashtag(id));\n }\n }\n\n render () {\n const { hasUnread, columnId, multiColumn, tag, intl } = this.props;\n const { id, local } = this.props.params;\n const pinned = !!columnId;\n const { signedIn } = this.context.identity;\n\n let followButton;\n\n if (tag) {\n const following = tag.get('following');\n\n followButton = (\n <button className={classNames('column-header__button')} onClick={this.handleFollow} disabled={!signedIn} active={following} title={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)} aria-label={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)}>\n <Icon id={following ? 'user-times' : 'user-plus'} fixedWidth className='column-header__icon' />\n </button>\n );\n }\n\n return (\n <Column bindToDocument={!multiColumn} ref={this.setRef} label={`#${id}`}>\n <ColumnHeader\n icon='hashtag'\n active={hasUnread}\n title={this.title()}\n onPin={this.handlePin}\n onMove={this.handleMove}\n onClick={this.handleHeaderClick}\n pinned={pinned}\n multiColumn={multiColumn}\n extraButton={followButton}\n showBackButton\n >\n {columnId && <ColumnSettingsContainer columnId={columnId} />}\n </ColumnHeader>\n\n <StatusListContainer\n trackScroll={!pinned}\n scrollKey={`hashtag_timeline-${columnId}`}\n timelineId={`hashtag:${id}${local ? ':local' : ''}`}\n onLoadMore={this.handleLoadMore}\n emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />}\n bindToDocument={!multiColumn}\n />\n\n <Helmet>\n <title>#{id}</title>\n <meta name='robots' content='noindex' />\n </Helmet>\n </Column>\n );\n }\n\n}\n"],"sourceRoot":""}