{"version":3,"sources":["webpack:///app/javascript/opt/mastodon/app/javascript/flavours/glitch/actions/tags_typed.ts","webpack:///app/javascript/opt/mastodon/app/javascript/flavours/glitch/api/tags.ts","webpack:///app/javascript/opt/mastodon/app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.tsx","webpack:///app/javascript/opt/mastodon/app/javascript/flavours/glitch/features/hashtag_timeline/components/column_settings.jsx","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.jsx"],"names":["fetchHashtag","createDataLoadingThunk","_ref","tagId","apiRequestGet","apiGetTag","followHashtag","_ref2","apiRequestPost","apiFollowTag","unfollowHashtag","_ref3","apiUnfollowTag","messages","defineMessages","id","defaultMessage","adminModeration","usesRenderer","displayNumber","pluralReady","_jsx","FormattedMessage","values","count","counter","peopleRenderer","usesTodayRenderer","HashtagHeader","intl","useIntl","signedIn","permissions","useIdentity","dispatch","useAppDispatch","tag","setTag","useState","useEffect","then","result","isFulfilled","payload","menu","useMemo","tmp","PERMISSION_MANAGE_TAXONOMIES","push","text","formatMessage","name","href","handleFollow","useCallback","following","hashtag","uses","people","history","reduce","arr","day","parseInt","accounts","dividingCircle","className","length","DropdownMenu","disabled","items","icon","iconComponent","MoreHorizIcon","size","direction","Button","onClick","ShortNumber","value","renderer","placeholder","noOptions","ColumnSettings","PureComponent","constructor","arguments","_defineProperty","open","this","hasTags","mode","oldValue","tags","maxFeedHashtags","props","onChange","state","setState","map","includes","settings","getIn","toJS","modeSelect","modeLabel","NonceProvider","nonce","document","querySelector","content","cacheKey","AsyncSelect","isMulti","autoFocus","onSelect","loadOptions","onLoad","classNamePrefix","noOptionsMessage","render","SettingToggle","settingPath","label","Toggle","onToggle","checked","injectIntl","connect","mapStateToProps","columnId","columns","index","findIndex","c","get","api","params","q","type","response","data","hashtags","mapDispatchToProps","key","changeColumnParams","HashtagTimeline","removeColumn","addColumn","title","additionalFor","additional","join","dir","moveColumn","column","scrollTop","maxId","local","expandHashtagTimeline","_subscribe","undefined","identity","any","all","none","disconnects","connectHashtagStream","status","filter","_unsubscribe","disconnect","_unload","clearTimeline","_load","componentDidMount","componentDidUpdate","prevProps","_isEqual","componentWillUnmount","hasUnread","multiColumn","pinned","_jsxs","Column","bindToDocument","ref","setRef","children","ColumnHeader","TagIcon","active","onPin","handlePin","onMove","handleMove","handleHeaderClick","showBackButton","ColumnSettingsContainer","StatusListContainer","prepend","alwaysPrepend","trackScroll","scrollKey","timelineId","onLoadMore","handleLoadMore","emptyMessage","Helmet","withIdentity"],"mappings":"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","file":"js/flavours/glitch/async/hashtag_timeline-8d6d79f4e4ee7d832639.chunk.js","sourcesContent":["import {\n  apiGetTag,\n  apiFollowTag,\n  apiUnfollowTag,\n} from 'flavours/glitch/api/tags';\nimport { createDataLoadingThunk } from 'flavours/glitch/store/typed_functions';\n\nexport const fetchHashtag = createDataLoadingThunk(\n  'tags/fetch',\n  ({ tagId }: { tagId: string }) => apiGetTag(tagId),\n);\n\nexport const followHashtag = createDataLoadingThunk(\n  'tags/follow',\n  ({ tagId }: { tagId: string }) => apiFollowTag(tagId),\n);\n\nexport const unfollowHashtag = createDataLoadingThunk(\n  'tags/unfollow',\n  ({ tagId }: { tagId: string }) => apiUnfollowTag(tagId),\n);\n","import { apiRequestPost, apiRequestGet } from 'flavours/glitch/api';\nimport type { ApiHashtagJSON } from 'flavours/glitch/api_types/tags';\n\nexport const apiGetTag = (tagId: string) =>\n  apiRequestGet<ApiHashtagJSON>(`v1/tags/${tagId}`);\n\nexport const apiFollowTag = (tagId: string) =>\n  apiRequestPost<ApiHashtagJSON>(`v1/tags/${tagId}/follow`);\n\nexport const apiUnfollowTag = (tagId: string) =>\n  apiRequestPost<ApiHashtagJSON>(`v1/tags/${tagId}/unfollow`);\n","import { useCallback, useMemo, useState, useEffect } from 'react';\n\nimport { defineMessages, useIntl, FormattedMessage } from 'react-intl';\n\nimport { isFulfilled } from '@reduxjs/toolkit';\n\nimport MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';\nimport {\n  fetchHashtag,\n  followHashtag,\n  unfollowHashtag,\n} from 'flavours/glitch/actions/tags_typed';\nimport type { ApiHashtagJSON } from 'flavours/glitch/api_types/tags';\nimport { Button } from 'flavours/glitch/components/button';\nimport { ShortNumber } from 'flavours/glitch/components/short_number';\nimport DropdownMenu from 'flavours/glitch/containers/dropdown_menu_container';\nimport { useIdentity } from 'flavours/glitch/identity_context';\nimport { PERMISSION_MANAGE_TAXONOMIES } from 'flavours/glitch/permissions';\nimport { useAppDispatch } from 'flavours/glitch/store';\n\nconst messages = defineMessages({\n  followHashtag: { id: 'hashtag.follow', defaultMessage: 'Follow hashtag' },\n  unfollowHashtag: {\n    id: 'hashtag.unfollow',\n    defaultMessage: 'Unfollow hashtag',\n  },\n  adminModeration: {\n    id: 'hashtag.admin_moderation',\n    defaultMessage: 'Open moderation interface for #{name}',\n  },\n});\n\nconst usesRenderer = (displayNumber: React.ReactNode, pluralReady: number) => (\n  <FormattedMessage\n    id='hashtag.counter_by_uses'\n    defaultMessage='{count, plural, one {{counter} post} other {{counter} posts}}'\n    values={{\n      count: pluralReady,\n      counter: <strong>{displayNumber}</strong>,\n    }}\n  />\n);\n\nconst peopleRenderer = (\n  displayNumber: React.ReactNode,\n  pluralReady: number,\n) => (\n  <FormattedMessage\n    id='hashtag.counter_by_accounts'\n    defaultMessage='{count, plural, one {{counter} participant} other {{counter} participants}}'\n    values={{\n      count: pluralReady,\n      counter: <strong>{displayNumber}</strong>,\n    }}\n  />\n);\n\nconst usesTodayRenderer = (\n  displayNumber: React.ReactNode,\n  pluralReady: number,\n) => (\n  <FormattedMessage\n    id='hashtag.counter_by_uses_today'\n    defaultMessage='{count, plural, one {{counter} post} other {{counter} posts}} today'\n    values={{\n      count: pluralReady,\n      counter: <strong>{displayNumber}</strong>,\n    }}\n  />\n);\n\nexport const HashtagHeader: React.FC<{\n  tagId: string;\n}> = ({ tagId }) => {\n  const intl = useIntl();\n  const { signedIn, permissions } = useIdentity();\n  const dispatch = useAppDispatch();\n  const [tag, setTag] = useState<ApiHashtagJSON>();\n\n  useEffect(() => {\n    void dispatch(fetchHashtag({ tagId })).then((result) => {\n      if (isFulfilled(result)) {\n        setTag(result.payload);\n      }\n\n      return '';\n    });\n  }, [dispatch, tagId, setTag]);\n\n  const menu = useMemo(() => {\n    const tmp = [];\n\n    if (\n      tag &&\n      signedIn &&\n      (permissions & PERMISSION_MANAGE_TAXONOMIES) ===\n        PERMISSION_MANAGE_TAXONOMIES\n    ) {\n      tmp.push({\n        text: intl.formatMessage(messages.adminModeration, { name: tag.id }),\n        href: `/admin/tags/${tag.id}`,\n      });\n    }\n\n    return tmp;\n  }, [signedIn, permissions, intl, tag]);\n\n  const handleFollow = useCallback(() => {\n    if (!signedIn || !tag) {\n      return;\n    }\n\n    if (tag.following) {\n      setTag((hashtag) => hashtag && { ...hashtag, following: false });\n\n      void dispatch(unfollowHashtag({ tagId })).then((result) => {\n        if (isFulfilled(result)) {\n          setTag(result.payload);\n        }\n\n        return '';\n      });\n    } else {\n      setTag((hashtag) => hashtag && { ...hashtag, following: true });\n\n      void dispatch(followHashtag({ tagId })).then((result) => {\n        if (isFulfilled(result)) {\n          setTag(result.payload);\n        }\n\n        return '';\n      });\n    }\n  }, [dispatch, setTag, signedIn, tag, tagId]);\n\n  if (!tag) {\n    return null;\n  }\n\n  const [uses, people] = tag.history.reduce(\n    (arr, day) => [\n      arr[0] + parseInt(day.uses),\n      arr[1] + parseInt(day.accounts),\n    ],\n    [0, 0],\n  );\n  const dividingCircle = <span aria-hidden>{' · '}</span>;\n\n  return (\n    <div className='hashtag-header'>\n      <div className='hashtag-header__header'>\n        <h1>#{tag.name}</h1>\n\n        <div className='hashtag-header__header__buttons'>\n          {menu.length > 0 && (\n            <DropdownMenu\n              disabled={menu.length === 0}\n              items={menu}\n              icon='ellipsis-v'\n              iconComponent={MoreHorizIcon}\n              size={24}\n              direction='right'\n            />\n          )}\n\n          <Button\n            onClick={handleFollow}\n            text={intl.formatMessage(\n              tag.following ? messages.unfollowHashtag : messages.followHashtag,\n            )}\n            disabled={!signedIn}\n          />\n        </div>\n      </div>\n\n      <div>\n        <ShortNumber value={uses} renderer={usesRenderer} />\n        {dividingCircle}\n        <ShortNumber value={people} renderer={peopleRenderer} />\n        {dividingCircle}\n        <ShortNumber\n          value={parseInt(tag.history[0].uses)}\n          renderer={usesTodayRenderer}\n        />\n      </div>\n    </div>\n  );\n};\n","import PropTypes from 'prop-types';\nimport { PureComponent } from 'react';\n\nimport { defineMessages, injectIntl, FormattedMessage } from 'react-intl';\n\nimport ImmutablePropTypes from 'react-immutable-proptypes';\n\nimport { NonceProvider } from 'react-select';\nimport AsyncSelect from 'react-select/async';\nimport Toggle from 'react-toggle';\n\nimport { maxFeedHashtags } from 'flavours/glitch/initial_state';\n\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\nclass ColumnSettings extends 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 the number of configured\n    // tags, but allow removing tags that were already added before\n    if ((value.length > maxFeedHashtags) && !(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 className='column-settings'>\n        <section>\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\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        </section>\n      </div>\n    );\n  }\n\n}\n\nexport default injectIntl(ColumnSettings);\n","import { connect } from 'react-redux';\n\nimport { changeColumnParams } from '../../../actions/columns';\nimport api from '../../../api';\nimport ColumnSettings from '../components/column_settings';\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().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 PropTypes from 'prop-types';\nimport { PureComponent } from 'react';\n\nimport { FormattedMessage } from 'react-intl';\n\nimport { Helmet } from 'react-helmet';\n\nimport { connect } from 'react-redux';\n\nimport { isEqual } from 'lodash';\n\nimport TagIcon from '@/material-icons/400-24px/tag.svg?react';\nimport { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns';\nimport { connectHashtagStream } from 'flavours/glitch/actions/streaming';\nimport { expandHashtagTimeline, clearTimeline } from 'flavours/glitch/actions/timelines';\nimport Column from 'flavours/glitch/components/column';\nimport ColumnHeader from 'flavours/glitch/components/column_header';\nimport { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';\n\nimport StatusListContainer from '../ui/containers/status_list_container';\n\nimport { HashtagHeader } from './components/hashtag_header';\nimport ColumnSettingsContainer from './containers/column_settings_container';\n\nconst mapStateToProps = (state, props) => ({\n  hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${props.params.local ? ':local' : ''}`, 'unread']) > 0,\n});\n\nclass HashtagTimeline extends PureComponent {\n  disconnects = [];\n\n  static propTypes = {\n    identity: identityContextPropShape,\n    params: PropTypes.object.isRequired,\n    columnId: PropTypes.string,\n    dispatch: PropTypes.func.isRequired,\n    hasUnread: PropTypes.bool,\n    multiColumn: PropTypes.bool,\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.props.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  }\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  render () {\n    const { hasUnread, columnId, multiColumn } = this.props;\n    const { id, local } = this.props.params;\n    const pinned = !!columnId;\n\n    return (\n      <Column bindToDocument={!multiColumn} ref={this.setRef} label={`#${id}`}>\n        <ColumnHeader\n          icon='hashtag'\n          iconComponent={TagIcon}\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          showBackButton\n        >\n          {columnId && <ColumnSettingsContainer columnId={columnId} />}\n        </ColumnHeader>\n\n        <StatusListContainer\n          prepend={pinned ? null : <HashtagHeader tagId={id} />}\n          alwaysPrepend\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\nexport default connect(mapStateToProps)(withIdentity(HashtagTimeline));\n"],"sourceRoot":""}