gab-social/app/javascript/gabsocial/components/status_action_bar.js

238 lines
7.2 KiB
JavaScript
Raw Normal View History

import React from 'react'
import PropTypes from 'prop-types'
2020-02-28 15:20:47 +00:00
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { defineMessages, injectIntl } from 'react-intl'
2020-04-24 04:17:27 +01:00
import { NavLink } from 'react-router-dom'
import { me } from '../initial_state'
2020-03-07 04:53:28 +00:00
import Text from './text'
2020-03-06 15:38:22 +00:00
import StatusActionBarItem from './status_action_bar_item'
import { CX } from '../constants'
class StatusActionBar extends ImmutablePureComponent {
2020-11-25 21:22:37 +00:00
// updateOnProps = ['status']
handleShareClick = () => {
this.props.onShare(this.shareButton, this.props.status)
}
handleReplyClick = () => {
2020-05-02 07:25:55 +01:00
this.props.onReply(this.props.status, null, true)
}
2020-03-04 22:26:01 +00:00
handleFavoriteClick = () => {
2020-04-22 06:00:11 +01:00
this.props.onFavorite(this.props.status)
}
handleRepostClick = () => {
this.props.onRepost(this.props.status)
}
handleQuoteClick = () => {
this.props.onQuote(this.props.status)
2020-03-25 03:08:43 +00:00
}
2020-04-17 06:35:46 +01:00
openLikesList = () => {
2020-05-03 06:22:49 +01:00
this.props.onOpenLikes(this.props.status)
2020-04-17 06:35:46 +01:00
}
openRepostsList = () => {
2020-05-03 06:22:49 +01:00
this.props.onOpenReposts(this.props.status)
2020-04-17 06:35:46 +01:00
}
setShareButton = (n) => {
this.shareButton = n
2020-04-24 04:17:27 +01:00
}
2020-02-28 15:20:47 +00:00
render() {
const {
status,
intl,
isCompact,
} = this.props
2020-02-28 15:20:47 +00:00
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'))
2020-02-28 15:20:47 +00:00
const replyCount = status.get('replies_count')
2020-03-04 22:50:15 +00:00
const repostCount = status.get('reblogs_count')
2020-04-07 02:53:23 +01:00
const favoriteCount = status.get('favourites_count')
2020-03-04 22:50:15 +00:00
const hasInteractions = favoriteCount > 0 || replyCount > 0 || repostCount > 0
2020-04-02 04:17:21 +01:00
const shouldCondense = (
!!status.get('card') ||
status.get('media_attachments').size > 0 ||
!!status.get('quote')
) && !hasInteractions
2020-02-14 00:40:04 +00:00
2020-04-24 04:17:27 +01:00
const statusUrl = `/${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`
const myStatus = status.getIn(['account', 'id']) === me
2020-04-24 04:17:27 +01:00
2020-04-29 23:32:49 +01:00
const containerClasses = CX({
d: 1,
px10: !isCompact,
2020-03-11 23:56:18 +00:00
mt10: !shouldCondense,
mt5: shouldCondense,
2020-02-14 00:40:04 +00:00
})
2020-04-29 23:32:49 +01:00
const innerContainerClasses = CX({
d: 1,
2020-03-11 23:56:18 +00:00
py2: 1,
2020-02-14 00:40:04 +00:00
flexRow: 1,
w100PC: 1,
borderTop1PX: !shouldCondense && !isCompact,
borderColorSecondary: !shouldCondense || isCompact,
borderBottom1PX: isCompact,
mt5: hasInteractions,
2020-02-14 00:40:04 +00:00
})
const likeBtnClasses = CX({
d: 1,
text: 1,
cursorPointer: myStatus,
fw400: 1,
noUnderline: 1,
underline_onHover: myStatus,
bgTransparent: 1,
mr10: 1,
py5: 1,
})
2020-04-29 23:32:49 +01:00
const interactionBtnClasses = CX({
d: 1,
2020-02-14 00:40:04 +00:00
text: 1,
cursorPointer: 1,
fw400: 1,
2020-04-24 04:17:27 +01:00
noUnderline: 1,
2020-04-17 06:35:46 +01:00
underline_onHover: 1,
2020-04-29 23:32:49 +01:00
bgTransparent: 1,
2020-03-11 23:56:18 +00:00
mr10: 1,
py5: 1,
2020-02-14 00:40:04 +00:00
})
const interactionContainerClasses = CX({
d: 1,
flexRow: 1,
aiEnd: 1,
px5: !isCompact,
px15: isCompact,
})
2020-02-08 06:12:01 +00:00
return (
2020-02-14 00:40:04 +00:00
<div className={containerClasses}>
{
hasInteractions &&
<div className={interactionContainerClasses}>
2020-03-07 04:53:28 +00:00
{
favoriteCount > 0 &&
<button
className={likeBtnClasses}
onClick={this.openLikesList}
disabled={!myStatus}
>
2020-03-26 03:11:32 +00:00
<Text color='secondary' size='small'>
2020-04-22 06:00:11 +01:00
{intl.formatMessage(messages.likesLabel, {
2020-04-02 17:57:04 +01:00
number: favoriteCount,
})}
2020-03-07 04:53:28 +00:00
</Text>
2020-02-14 00:40:04 +00:00
</button>
}
2020-03-07 04:53:28 +00:00
{
replyCount > 0 &&
2020-04-24 04:17:27 +01:00
<NavLink
className={interactionBtnClasses}
to={statusUrl}
>
2020-03-26 03:11:32 +00:00
<Text color='secondary' size='small'>
2020-04-22 06:00:11 +01:00
{intl.formatMessage(messages.commentsLabel, {
2020-04-02 17:57:04 +01:00
number: replyCount,
})}
2020-03-07 04:53:28 +00:00
</Text>
2020-04-24 04:17:27 +01:00
</NavLink>
2020-02-14 00:40:04 +00:00
}
2020-03-07 04:53:28 +00:00
{
repostCount > 0 &&
2020-04-17 06:35:46 +01:00
<button className={interactionBtnClasses} onClick={this.openRepostsList}>
2020-03-26 03:11:32 +00:00
<Text color='secondary' size='small'>
2020-04-22 06:00:11 +01:00
{intl.formatMessage(messages.repostsLabel, {
2020-04-02 17:57:04 +01:00
number: repostCount,
})}
2020-03-07 04:53:28 +00:00
</Text>
2020-02-14 00:40:04 +00:00
</button>
}
</div>
}
<div className={innerContainerClasses}>
<div className={[_s.d, _s.flexRow, _s.py2, _s.w100PC].join(' ')}>
2020-03-07 04:53:28 +00:00
<StatusActionBarItem
title={intl.formatMessage(messages.like)}
2020-04-02 17:57:04 +01:00
icon={!!status.get('favourited') ? 'liked' : 'like'}
active={!!status.get('favourited')}
2020-03-07 04:53:28 +00:00
onClick={this.handleFavoriteClick}
isCompact={isCompact}
2020-03-07 04:53:28 +00:00
/>
<StatusActionBarItem
title={intl.formatMessage(messages.comment)}
2020-03-07 04:53:28 +00:00
icon='comment'
onClick={this.handleReplyClick}
isCompact={isCompact}
2020-03-07 04:53:28 +00:00
/>
<StatusActionBarItem
title={intl.formatMessage(messages.repost)}
2020-04-22 06:00:11 +01:00
altTitle={!publicStatus ? intl.formatMessage(messages.cannot_repost) : ''}
2020-04-07 02:53:23 +01:00
icon={!publicStatus ? 'lock' : 'repost'}
2020-03-07 04:53:28 +00:00
disabled={!publicStatus}
active={!!status.get('reblogged')}
onClick={this.handleRepostClick}
isCompact={isCompact}
2020-03-07 04:53:28 +00:00
/>
<StatusActionBarItem
title={intl.formatMessage(messages.quote)}
altTitle={!publicStatus ? intl.formatMessage(messages.cannot_repost) : ''}
icon={!publicStatus ? 'lock' : 'quote'}
disabled={!publicStatus}
onClick={this.handleQuoteClick}
isCompact={isCompact}
/>
<StatusActionBarItem
title={intl.formatMessage(messages.share)}
altTitle={intl.formatMessage(messages.share)}
buttonRef={this.setShareButton}
icon='share'
onClick={this.handleShareClick}
isCompact={isCompact}
/>
2020-02-14 00:40:04 +00:00
</div>
</div>
</div>
2020-02-28 15:20:47 +00:00
)
}
}
const messages = defineMessages({
share: { id: 'status.share', defaultMessage: 'Share' },
comment: { id: 'status.comment', defaultMessage: 'Comment' },
quote: { id: 'status.quote', defaultMessage: 'Quote' },
repost: { id: 'status.repost', defaultMessage: 'Repost' },
cannot_repost: { id: 'status.cannot_repost', defaultMessage: 'This post cannot be reposted' },
like: { id: 'status.like', defaultMessage: 'Like' },
likesLabel: { id: 'likes.label', defaultMessage: '{number, plural, one {# like} other {# likes}}' },
repostsLabel: { id: 'reposts.label', defaultMessage: '{number, plural, one {# repost} other {# reposts}}' },
commentsLabel: { id: 'comments.label', defaultMessage: '{number, plural, one {# comment} other {# comments}}' },
})
StatusActionBar.propTypes = {
intl: PropTypes.object.isRequired,
onFavorite: PropTypes.func.isRequired,
onQuote: PropTypes.func.isRequired,
onReply: PropTypes.func.isRequired,
onRepost: PropTypes.func.isRequired,
onShare: PropTypes.func.isRequired,
status: ImmutablePropTypes.map.isRequired,
onOpenLikes: PropTypes.func.isRequired,
onOpenReposts: PropTypes.func.isRequired,
isCompact: PropTypes.bool,
}
export default injectIntl(StatusActionBar)