{"version":3,"sources":["webpack:///./app/javascript/mastodon/features/account_gallery/components/media_item.jsx","webpack:///./app/javascript/mastodon/features/account_gallery/index.jsx"],"names":["MediaItem","ImmutablePureComponent","constructor","arguments","state","visible","displayMedia","this","props","attachment","getIn","loaded","handleImageLoad","setState","handleMouseEnter","e","hoverToPlay","target","play","handleMouseLeave","pause","currentTime","handleClick","button","ctrlKey","metaKey","preventDefault","onOpenMedia","autoPlayGif","indexOf","get","render","displayWidth","width","Math","floor","height","status","title","thumbnail","label","icon","content","includes","_jsx","src","alt","lang","onLoad","Icon","id","x","y","style","objectPosition","className","role","onMouseEnter","onMouseLeave","autoPlay","playsInline","loop","muted","href","onClick","rel","Blurhash","hash","classNames","dummy","useBlurhash","propTypes","ImmutablePropTypes","map","isRequired","PropTypes","number","func","LoadMoreMedia","handleLoadMore","onLoadMore","maxId","LoadMore","disabled","string","AccountGallery","handleScrollToBottom","hasMore","attachments","size","last","undefined","handleScroll","scrollTop","scrollHeight","clientHeight","isLoading","dispatch","expandAccountMediaTimeline","accountId","handleLoadOlder","handleOpenMedia","statusId","openModal","modalType","modalProps","media","options","index","findIndex","handleRef","c","offsetWidth","_load","isAccount","fetchAccount","componentDidMount","params","acct","lookupAccount","componentDidUpdate","prevProps","multiColumn","blockedBy","suspended","BundleColumnError","errorType","Column","LoadingIndicator","emptyMessage","loadOlder","FormattedMessage","defaultMessage","ColumnBackButton","ScrollContainer","scrollKey","onScroll","HeaderContainer","_jsxs","ref","children","shape","list","bool","connect","mapStateToProps","_ref","normalizeForLookup","getAccountGallery"],"mappings":"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","file":"js/features/account_gallery-b89aaa9f99b24bad7ebf.chunk.js","sourcesContent":["import PropTypes from 'prop-types';\n\nimport classNames from 'classnames';\n\nimport ImmutablePropTypes from 'react-immutable-proptypes';\nimport ImmutablePureComponent from 'react-immutable-pure-component';\n\nimport { Blurhash } from 'mastodon/components/blurhash';\nimport { Icon }  from 'mastodon/components/icon';\nimport { autoPlayGif, displayMedia, useBlurhash } from 'mastodon/initial_state';\n\nexport default class MediaItem extends ImmutablePureComponent {\n\n  static propTypes = {\n    attachment: ImmutablePropTypes.map.isRequired,\n    displayWidth: PropTypes.number.isRequired,\n    onOpenMedia: PropTypes.func.isRequired,\n  };\n\n  state = {\n    visible: displayMedia !== 'hide_all' && !this.props.attachment.getIn(['status', 'sensitive']) || displayMedia === 'show_all',\n    loaded: false,\n  };\n\n  handleImageLoad = () => {\n    this.setState({ loaded: true });\n  };\n\n  handleMouseEnter = e => {\n    if (this.hoverToPlay()) {\n      e.target.play();\n    }\n  };\n\n  handleMouseLeave = e => {\n    if (this.hoverToPlay()) {\n      e.target.pause();\n      e.target.currentTime = 0;\n    }\n  };\n\n  hoverToPlay () {\n    return !autoPlayGif && ['gifv', 'video'].indexOf(this.props.attachment.get('type')) !== -1;\n  }\n\n  handleClick = e => {\n    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {\n      e.preventDefault();\n\n      if (this.state.visible) {\n        this.props.onOpenMedia(this.props.attachment);\n      } else {\n        this.setState({ visible: true });\n      }\n    }\n  };\n\n  render () {\n    const { attachment, displayWidth } = this.props;\n    const { visible, loaded } = this.state;\n\n    const width  = `${Math.floor((displayWidth - 4) / 3) - 4}px`;\n    const height = width;\n    const status = attachment.get('status');\n    const title  = status.get('spoiler_text') || attachment.get('description');\n\n    let thumbnail, label, icon, content;\n\n    if (!visible) {\n      icon = (\n        <span className='account-gallery__item__icons'>\n          <Icon id='eye-slash' />\n        </span>\n      );\n    } else {\n      if (['audio', 'video'].includes(attachment.get('type'))) {\n        content = (\n          <img\n            src={attachment.get('preview_url') || status.getIn(['account', 'avatar_static'])}\n            alt={attachment.get('description')}\n            lang={status.get('language')}\n            onLoad={this.handleImageLoad}\n          />\n        );\n\n        if (attachment.get('type') === 'audio') {\n          label = <Icon id='music' />;\n        } else {\n          label = <Icon id='play' />;\n        }\n      } else if (attachment.get('type') === 'image') {\n        const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;\n        const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;\n        const x      = ((focusX /  2) + .5) * 100;\n        const y      = ((focusY / -2) + .5) * 100;\n\n        content = (\n          <img\n            src={attachment.get('preview_url')}\n            alt={attachment.get('description')}\n            lang={status.get('language')}\n            style={{ objectPosition: `${x}% ${y}%` }}\n            onLoad={this.handleImageLoad}\n          />\n        );\n      } else if (attachment.get('type') === 'gifv') {\n        content = (\n          <video\n            className='media-gallery__item-gifv-thumbnail'\n            aria-label={attachment.get('description')}\n            title={attachment.get('description')}\n            lang={status.get('language')}\n            role='application'\n            src={attachment.get('url')}\n            onMouseEnter={this.handleMouseEnter}\n            onMouseLeave={this.handleMouseLeave}\n            autoPlay={autoPlayGif}\n            playsInline\n            loop\n            muted\n          />\n        );\n\n        label = 'GIF';\n      }\n\n      thumbnail = (\n        <div className='media-gallery__gifv'>\n          {content}\n\n          {label && (\n            <div className='media-gallery__item__badges'>\n              <span className='media-gallery__gifv__label'>{label}</span>\n            </div>\n          )}\n        </div>\n      );\n    }\n\n    return (\n      <div className='account-gallery__item' style={{ width, height }}>\n        <a className='media-gallery__item-thumbnail' href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'>\n          <Blurhash\n            hash={attachment.get('blurhash')}\n            className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })}\n            dummy={!useBlurhash}\n          />\n\n          {visible ? thumbnail : icon}\n        </a>\n      </div>\n    );\n  }\n\n}\n","import PropTypes from 'prop-types';\n\nimport { FormattedMessage } from 'react-intl';\n\nimport ImmutablePropTypes from 'react-immutable-proptypes';\nimport ImmutablePureComponent from 'react-immutable-pure-component';\nimport { connect } from 'react-redux';\n\nimport { lookupAccount, fetchAccount } from 'mastodon/actions/accounts';\nimport { openModal } from 'mastodon/actions/modal';\nimport ColumnBackButton from 'mastodon/components/column_back_button';\nimport { LoadMore } from 'mastodon/components/load_more';\nimport { LoadingIndicator } from 'mastodon/components/loading_indicator';\nimport ScrollContainer from 'mastodon/containers/scroll_container';\nimport BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';\nimport { normalizeForLookup } from 'mastodon/reducers/accounts_map';\nimport { getAccountGallery } from 'mastodon/selectors';\n\nimport { expandAccountMediaTimeline } from '../../actions/timelines';\nimport HeaderContainer from '../account_timeline/containers/header_container';\nimport Column from '../ui/components/column';\n\nimport MediaItem from './components/media_item';\n\nconst mapStateToProps = (state, { params: { acct, id } }) => {\n  const accountId = id || state.getIn(['accounts_map', normalizeForLookup(acct)]);\n\n  if (!accountId) {\n    return {\n      isLoading: true,\n    };\n  }\n\n  return {\n    accountId,\n    isAccount: !!state.getIn(['accounts', accountId]),\n    attachments: getAccountGallery(state, accountId),\n    isLoading: state.getIn(['timelines', `account:${accountId}:media`, 'isLoading']),\n    hasMore: state.getIn(['timelines', `account:${accountId}:media`, 'hasMore']),\n    suspended: state.getIn(['accounts', accountId, 'suspended'], false),\n    blockedBy: state.getIn(['relationships', accountId, 'blocked_by'], false),\n  };\n};\n\nclass LoadMoreMedia extends ImmutablePureComponent {\n\n  static propTypes = {\n    maxId: PropTypes.string,\n    onLoadMore: PropTypes.func.isRequired,\n  };\n\n  handleLoadMore = () => {\n    this.props.onLoadMore(this.props.maxId);\n  };\n\n  render () {\n    return (\n      <LoadMore\n        disabled={this.props.disabled}\n        onClick={this.handleLoadMore}\n      />\n    );\n  }\n\n}\n\nclass AccountGallery extends ImmutablePureComponent {\n\n  static propTypes = {\n    params: PropTypes.shape({\n      acct: PropTypes.string,\n      id: PropTypes.string,\n    }).isRequired,\n    accountId: PropTypes.string,\n    dispatch: PropTypes.func.isRequired,\n    attachments: ImmutablePropTypes.list.isRequired,\n    isLoading: PropTypes.bool,\n    hasMore: PropTypes.bool,\n    isAccount: PropTypes.bool,\n    blockedBy: PropTypes.bool,\n    suspended: PropTypes.bool,\n    multiColumn: PropTypes.bool,\n  };\n\n  state = {\n    width: 323,\n  };\n\n  _load () {\n    const { accountId, isAccount, dispatch } = this.props;\n\n    if (!isAccount) dispatch(fetchAccount(accountId));\n    dispatch(expandAccountMediaTimeline(accountId));\n  }\n\n  componentDidMount () {\n    const { params: { acct }, accountId, dispatch } = this.props;\n\n    if (accountId) {\n      this._load();\n    } else {\n      dispatch(lookupAccount(acct));\n    }\n  }\n\n  componentDidUpdate (prevProps) {\n    const { params: { acct }, accountId, dispatch } = this.props;\n\n    if (prevProps.accountId !== accountId && accountId) {\n      this._load();\n    } else if (prevProps.params.acct !== acct) {\n      dispatch(lookupAccount(acct));\n    }\n  }\n\n  handleScrollToBottom = () => {\n    if (this.props.hasMore) {\n      this.handleLoadMore(this.props.attachments.size > 0 ? this.props.attachments.last().getIn(['status', 'id']) : undefined);\n    }\n  };\n\n  handleScroll = e => {\n    const { scrollTop, scrollHeight, clientHeight } = e.target;\n    const offset = scrollHeight - scrollTop - clientHeight;\n\n    if (150 > offset && !this.props.isLoading) {\n      this.handleScrollToBottom();\n    }\n  };\n\n  handleLoadMore = maxId => {\n    this.props.dispatch(expandAccountMediaTimeline(this.props.accountId, { maxId }));\n  };\n\n  handleLoadOlder = e => {\n    e.preventDefault();\n    this.handleScrollToBottom();\n  };\n\n  handleOpenMedia = attachment => {\n    const { dispatch } = this.props;\n    const statusId = attachment.getIn(['status', 'id']);\n    const lang = attachment.getIn(['status', 'language']);\n\n    if (attachment.get('type') === 'video') {\n      dispatch(openModal({\n        modalType: 'VIDEO',\n        modalProps: { media: attachment, statusId, lang, options: { autoPlay: true } },\n      }));\n    } else if (attachment.get('type') === 'audio') {\n      dispatch(openModal({\n        modalType: 'AUDIO',\n        modalProps: { media: attachment, statusId, lang, options: { autoPlay: true } },\n      }));\n    } else {\n      const media = attachment.getIn(['status', 'media_attachments']);\n      const index = media.findIndex(x => x.get('id') === attachment.get('id'));\n\n      dispatch(openModal({\n        modalType: 'MEDIA',\n        modalProps: { media, index, statusId, lang },\n      }));\n    }\n  };\n\n  handleRef = c => {\n    if (c) {\n      this.setState({ width: c.offsetWidth });\n    }\n  };\n\n  render () {\n    const { attachments, isLoading, hasMore, isAccount, multiColumn, blockedBy, suspended } = this.props;\n    const { width } = this.state;\n\n    if (!isAccount) {\n      return (\n        <BundleColumnError multiColumn={multiColumn} errorType='routing' />\n      );\n    }\n\n    if (!attachments && isLoading) {\n      return (\n        <Column>\n          <LoadingIndicator />\n        </Column>\n      );\n    }\n\n    let loadOlder = null;\n\n    if (hasMore && !(isLoading && attachments.size === 0)) {\n      loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />;\n    }\n\n    let emptyMessage;\n\n    if (suspended) {\n      emptyMessage = <FormattedMessage id='empty_column.account_suspended' defaultMessage='Account suspended' />;\n    } else if (blockedBy) {\n      emptyMessage = <FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' />;\n    }\n\n    return (\n      <Column>\n        <ColumnBackButton multiColumn={multiColumn} />\n\n        <ScrollContainer scrollKey='account_gallery'>\n          <div className='scrollable scrollable--flex' onScroll={this.handleScroll}>\n            <HeaderContainer accountId={this.props.accountId} />\n\n            {(suspended || blockedBy) ? (\n              <div className='empty-column-indicator'>\n                {emptyMessage}\n              </div>\n            ) : (\n              <div role='feed' className='account-gallery__container' ref={this.handleRef}>\n                {attachments.map((attachment, index) => attachment === null ? (\n                  <LoadMoreMedia key={'more:' + attachments.getIn(index + 1, 'id')} maxId={index > 0 ? attachments.getIn(index - 1, 'id') : null} onLoadMore={this.handleLoadMore} />\n                ) : (\n                  <MediaItem key={attachment.get('id')} attachment={attachment} displayWidth={width} onOpenMedia={this.handleOpenMedia} />\n                ))}\n\n                {loadOlder}\n              </div>\n            )}\n\n            {isLoading && attachments.size === 0 && (\n              <div className='scrollable__append'>\n                <LoadingIndicator />\n              </div>\n            )}\n          </div>\n        </ScrollContainer>\n      </Column>\n    );\n  }\n\n}\n\nexport default connect(mapStateToProps)(AccountGallery);\n"],"sourceRoot":""}