diff options
Diffstat (limited to 'app/javascript/flavours/glitch/features/status/components/detailed_status.js')
-rw-r--r-- | app/javascript/flavours/glitch/features/status/components/detailed_status.js | 335 |
1 files changed, 0 insertions, 335 deletions
diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.js b/app/javascript/flavours/glitch/features/status/components/detailed_status.js deleted file mode 100644 index 907fc3f1c..000000000 --- a/app/javascript/flavours/glitch/features/status/components/detailed_status.js +++ /dev/null @@ -1,335 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import Avatar from 'flavours/glitch/components/avatar'; -import DisplayName from 'flavours/glitch/components/display_name'; -import StatusContent from 'flavours/glitch/components/status_content'; -import MediaGallery from 'flavours/glitch/components/media_gallery'; -import AttachmentList from 'flavours/glitch/components/attachment_list'; -import { Link } from 'react-router-dom'; -import { injectIntl, FormattedDate } from 'react-intl'; -import Card from './card'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import Video from 'flavours/glitch/features/video'; -import Audio from 'flavours/glitch/features/audio'; -import VisibilityIcon from 'flavours/glitch/components/status_visibility_icon'; -import scheduleIdleTask from '../../ui/util/schedule_idle_task'; -import classNames from 'classnames'; -import PollContainer from 'flavours/glitch/containers/poll_container'; -import Icon from 'flavours/glitch/components/icon'; -import AnimatedNumber from 'flavours/glitch/components/animated_number'; -import PictureInPicturePlaceholder from 'flavours/glitch/components/picture_in_picture_placeholder'; -import EditedTimestamp from 'flavours/glitch/components/edited_timestamp'; - -export default @injectIntl -class DetailedStatus extends ImmutablePureComponent { - - static contextTypes = { - router: PropTypes.object, - }; - - static propTypes = { - status: ImmutablePropTypes.map, - settings: ImmutablePropTypes.map.isRequired, - onOpenMedia: PropTypes.func.isRequired, - onOpenVideo: PropTypes.func.isRequired, - onToggleHidden: PropTypes.func, - onTranslate: PropTypes.func.isRequired, - expanded: PropTypes.bool, - measureHeight: PropTypes.bool, - onHeightChange: PropTypes.func, - domain: PropTypes.string.isRequired, - compact: PropTypes.bool, - showMedia: PropTypes.bool, - pictureInPicture: ImmutablePropTypes.contains({ - inUse: PropTypes.bool, - available: PropTypes.bool, - }), - onToggleMediaVisibility: PropTypes.func, - intl: PropTypes.object.isRequired, - }; - - state = { - height: null, - }; - - handleAccountClick = (e) => { - if (e.button === 0 && !(e.ctrlKey || e.altKey || e.metaKey) && this.context.router) { - e.preventDefault(); - let state = {...this.context.router.history.location.state}; - state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1; - this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`, state); - } - - e.stopPropagation(); - } - - parseClick = (e, destination) => { - if (e.button === 0 && !(e.ctrlKey || e.altKey || e.metaKey) && this.context.router) { - e.preventDefault(); - let state = {...this.context.router.history.location.state}; - state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1; - this.context.router.history.push(destination, state); - } - - e.stopPropagation(); - } - - handleOpenVideo = (options) => { - this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), options); - } - - _measureHeight (heightJustChanged) { - if (this.props.measureHeight && this.node) { - scheduleIdleTask(() => this.node && this.setState({ height: Math.ceil(this.node.scrollHeight) + 1 })); - - if (this.props.onHeightChange && heightJustChanged) { - this.props.onHeightChange(); - } - } - } - - setRef = c => { - this.node = c; - this._measureHeight(); - } - - componentDidUpdate (prevProps, prevState) { - this._measureHeight(prevState.height !== this.state.height); - } - - handleChildUpdate = () => { - this._measureHeight(); - } - - handleModalLink = e => { - e.preventDefault(); - - let href; - - if (e.target.nodeName !== 'A') { - href = e.target.parentNode.href; - } else { - href = e.target.href; - } - - window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes'); - } - - handleTranslate = () => { - const { onTranslate, status } = this.props; - onTranslate(status); - } - - render () { - const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status; - const { expanded, onToggleHidden, settings, pictureInPicture, intl } = this.props; - const outerStyle = { boxSizing: 'border-box' }; - const { compact } = this.props; - - if (!status) { - return null; - } - - let applicationLink = ''; - let reblogLink = ''; - let reblogIcon = 'retweet'; - let favouriteLink = ''; - let edited = ''; - - // Depending on user settings, some media are considered as parts of the - // contents (affected by CW) while other will be displayed outside of the - // CW. - let contentMedia = []; - let contentMediaIcons = []; - let extraMedia = []; - let extraMediaIcons = []; - let media = contentMedia; - let mediaIcons = contentMediaIcons; - - if (settings.getIn(['content_warnings', 'media_outside'])) { - media = extraMedia; - mediaIcons = extraMediaIcons; - } - - if (this.props.measureHeight) { - outerStyle.height = `${this.state.height}px`; - } - - if (pictureInPicture.get('inUse')) { - media.push(<PictureInPicturePlaceholder />); - mediaIcons.push('video-camera'); - } else if (status.get('media_attachments').size > 0) { - if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) { - media.push(<AttachmentList media={status.get('media_attachments')} />); - } else if (status.getIn(['media_attachments', 0, 'type']) === 'audio') { - const attachment = status.getIn(['media_attachments', 0]); - - media.push( - <Audio - src={attachment.get('url')} - alt={attachment.get('description')} - duration={attachment.getIn(['meta', 'original', 'duration'], 0)} - poster={attachment.get('preview_url') || status.getIn(['account', 'avatar_static'])} - backgroundColor={attachment.getIn(['meta', 'colors', 'background'])} - foregroundColor={attachment.getIn(['meta', 'colors', 'foreground'])} - accentColor={attachment.getIn(['meta', 'colors', 'accent'])} - sensitive={status.get('sensitive')} - visible={this.props.showMedia} - blurhash={attachment.get('blurhash')} - height={150} - onToggleVisibility={this.props.onToggleMediaVisibility} - />, - ); - mediaIcons.push('music'); - } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { - const attachment = status.getIn(['media_attachments', 0]); - media.push( - <Video - preview={attachment.get('preview_url')} - frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])} - blurhash={attachment.get('blurhash')} - src={attachment.get('url')} - alt={attachment.get('description')} - inline - sensitive={status.get('sensitive')} - letterbox={settings.getIn(['media', 'letterbox'])} - fullwidth={settings.getIn(['media', 'fullwidth'])} - preventPlayback={!expanded} - onOpenVideo={this.handleOpenVideo} - autoplay - visible={this.props.showMedia} - onToggleVisibility={this.props.onToggleMediaVisibility} - />, - ); - mediaIcons.push('video-camera'); - } else { - media.push( - <MediaGallery - standalone - sensitive={status.get('sensitive')} - media={status.get('media_attachments')} - letterbox={settings.getIn(['media', 'letterbox'])} - fullwidth={settings.getIn(['media', 'fullwidth'])} - hidden={!expanded} - onOpenMedia={this.props.onOpenMedia} - visible={this.props.showMedia} - onToggleVisibility={this.props.onToggleMediaVisibility} - />, - ); - mediaIcons.push('picture-o'); - } - } else if (status.get('card')) { - media.push(<Card sensitive={status.get('sensitive')} onOpenMedia={this.props.onOpenMedia} card={status.get('card')} />); - mediaIcons.push('link'); - } - - if (status.get('poll')) { - contentMedia.push(<PollContainer pollId={status.get('poll')} />); - contentMediaIcons.push('tasks'); - } - - if (status.get('application')) { - applicationLink = <React.Fragment> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener noreferrer'>{status.getIn(['application', 'name'])}</a></React.Fragment>; - } - - const visibilityLink = <React.Fragment> · <VisibilityIcon visibility={status.get('visibility')} /></React.Fragment>; - - if (status.get('visibility') === 'direct') { - reblogIcon = 'envelope'; - } else if (status.get('visibility') === 'private') { - reblogIcon = 'lock'; - } - - if (!['unlisted', 'public'].includes(status.get('visibility'))) { - reblogLink = null; - } else if (this.context.router) { - reblogLink = ( - <React.Fragment> - <React.Fragment> · </React.Fragment> - <Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/reblogs`} className='detailed-status__link'> - <Icon id={reblogIcon} /> - <span className='detailed-status__reblogs'> - <AnimatedNumber value={status.get('reblogs_count')} /> - </span> - </Link> - </React.Fragment> - ); - } else { - reblogLink = ( - <React.Fragment> - <React.Fragment> · </React.Fragment> - <a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}> - <Icon id={reblogIcon} /> - <span className='detailed-status__reblogs'> - <AnimatedNumber value={status.get('reblogs_count')} /> - </span> - </a> - </React.Fragment> - ); - } - - if (this.context.router) { - favouriteLink = ( - <Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/favourites`} className='detailed-status__link'> - <Icon id='star' /> - <span className='detailed-status__favorites'> - <AnimatedNumber value={status.get('favourites_count')} /> - </span> - </Link> - ); - } else { - favouriteLink = ( - <a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}> - <Icon id='star' /> - <span className='detailed-status__favorites'> - <AnimatedNumber value={status.get('favourites_count')} /> - </span> - </a> - ); - } - - if (status.get('edited_at')) { - edited = ( - <React.Fragment> - <React.Fragment> · </React.Fragment> - <EditedTimestamp statusId={status.get('id')} timestamp={status.get('edited_at')} /> - </React.Fragment> - ); - } - - return ( - <div style={outerStyle}> - <div ref={this.setRef} className={classNames('detailed-status', `detailed-status-${status.get('visibility')}`, { compact })} data-status-by={status.getIn(['account', 'acct'])}> - <a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'> - <div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div> - <DisplayName account={status.get('account')} localDomain={this.props.domain} /> - </a> - - <StatusContent - status={status} - media={contentMedia} - extraMedia={extraMedia} - mediaIcons={contentMediaIcons} - expanded={expanded} - collapsed={false} - onExpandedToggle={onToggleHidden} - onTranslate={this.handleTranslate} - parseClick={this.parseClick} - onUpdate={this.handleChildUpdate} - tagLinks={settings.get('tag_misleading_links')} - rewriteMentions={settings.get('rewrite_mentions')} - disabled - /> - - <div className='detailed-status__meta'> - <a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener noreferrer'> - <FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' /> - </a>{edited}{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink} - </div> - </div> - </div> - ); - } - -} |