hashtag in top of tag feed, scroll to comment, chat blocking, muting, filtering
This commit is contained in:
mgabdev
2020-12-21 18:30:46 -05:00
parent ee91809e8d
commit 67d94858dc
39 changed files with 576 additions and 179 deletions

View File

@@ -51,6 +51,7 @@ class Account extends ImmutablePureComponent {
showDismiss,
withBio,
isCard,
noClick,
} = this.props
if (!account) return null
@@ -105,6 +106,8 @@ class Account extends ImmutablePureComponent {
noUnderline: 1,
overflowHidden: 1,
flexNormal: 1,
outlineNone: 1,
bgTransparent: 1,
aiStart: !isCard,
aiCenter: isCard,
})
@@ -133,26 +136,28 @@ class Account extends ImmutablePureComponent {
<div className={containerClasses}>
<div className={innerContainerClasses}>
<NavLink
className={[_s.d, _s.noUnderline].join(' ')}
<Button
noClasses
className={[_s.d, _s.noUnderline, _s.outlineNone, _s.bgTransparent].join(' ')}
title={account.get('acct')}
to={`/${account.get('acct')}`}
to={noClick ? undefined : `/${account.get('acct')}`}
>
<Avatar account={account} size={avatarSize} />
</NavLink>
</Button>
<div className={[_s.d, _s.px10, _s.overflowHidden, _s.flexNormal].join(' ')}>
<div className={[_s.d, _s.flexRow, _s.aiCenter].join(' ')}>
<NavLink
<Button
noClasses
title={account.get('acct')}
to={`/${account.get('acct')}`}
to={noClick ? undefined : `/${account.get('acct')}`}
className={buttonClasses}
>
<div className={displayNameWrapperClasses}>
<DisplayName account={account} isMultiline={compact || isCard} />
</div>
{!compact && actionButton}
</NavLink>
</Button>
<div className={[_s.d].join(' ')}>
{dismissBtn}
@@ -232,6 +237,7 @@ Account.propTypes = {
dismissAction: PropTypes.func,
withBio: PropTypes.bool,
isCard: PropTypes.bool,
noClick: PropTypes.bool,
}
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Account))

View File

@@ -88,6 +88,14 @@ class Comment extends ImmutablePureComponent {
this.moreNode = c
}
setContainerNode = (c) => {
this.containerNode = c
if (this.props.isHighlighted && this.containerNode) {
this.containerNode.scrollIntoView({ behavior: 'smooth' });
}
}
render() {
const {
indent,
@@ -101,7 +109,7 @@ class Comment extends ImmutablePureComponent {
if (isHidden) {
return (
<div tabIndex='0'>
<div tabIndex='0' ref={this.setContainerNode}>
{status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])}
{status.get('content')}
</div>
@@ -133,7 +141,11 @@ class Comment extends ImmutablePureComponent {
})
return (
<div className={containerClasses} data-comment={status.get('id')}>
<div
className={containerClasses}
data-comment={status.get('id')}
ref={this.setContainerNode}
>
{
indent > 0 &&
<div className={[_s.d, _s.z3, _s.flexRow, _s.posAbs, _s.topNeg20PX, _s.left0, _s.bottom20PX, _s.aiCenter, _s.jcCenter].join(' ')}>

View File

@@ -1,10 +1,12 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Sparklines, SparklinesCurve } from 'react-sparklines'
import { FormattedMessage } from 'react-intl'
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { NavLink } from 'react-router-dom'
import Button from './button'
import Block from './block'
import Text from './text'
class HashtagItem extends ImmutablePureComponent {
@@ -12,44 +14,42 @@ class HashtagItem extends ImmutablePureComponent {
render() {
const { hashtag, isCompact } = this.props
if (!hashtag) return
const count = hashtag.get('history').map((block) => {
return parseInt(block.get('uses'))
}).reduce((a, c) => a + c)
return (
<NavLink
to={`/tags/${hashtag.get('name')}`}
className={[_s.d, _s.noUnderline, _s.bgSubtle_onHover, _s.px15, _s.py5].join(' ')}
>
<div className={[_s.d, _s.flexRow, _s.aiCenter].join(' ')}>
<div>
<Text color='brand' size='medium' weight='bold' className={[_s.py2, _s.lineHeight15].join(' ')}>
#{hashtag.get('name')}
</Text>
<Block>
<div className={[_s.d, _s.w100PC].join(' ')}>
<div className={[_s.d, _s.noUnderline, _s.px15, _s.py5].join(' ')}>
<div className={[_s.d, _s.flexRow, _s.aiCenter].join(' ')}>
<div>
<Text color='brand' size='medium' weight='bold' className={[_s.py2, _s.lineHeight15].join(' ')}>
#{hashtag.get('name')}
</Text>
</div>
</div>
{
!isCompact &&
<Text color='secondary' size='small' className={_s.py2}>
<FormattedMessage id='number_of_gabs' defaultMessage='{count} Gabs' values={{
count,
}} />
</Text>
}
</div>
{
!isCompact &&
<Button
isText
backgroundColor='none'
color='none'
title='Remove'
icon='close'
iconSize='8px'
iconClassName={_s.cSecondary}
className={_s.mlAuto}
/>
}
<Sparklines
width={50}
height={28}
data={hashtag.get('history').reverse().map((day) => day.get('uses')).toArray()}
>
<SparklinesCurve style={{ fill: 'none' }} />
</Sparklines>
</div>
{
!isCompact &&
<Text color='secondary' size='small' className={_s.py2}>
<FormattedMessage id='number_of_gabs' defaultMessage='{count} Gabs' values={{
count,
}} />
</Text>
}
</NavLink>
</Block>
)
}

View File

@@ -54,6 +54,7 @@ class ChatConversationOptionsPopover extends ImmutablePureComponent {
intl,
isXS,
isMuted,
isChatConversationRequest,
} = this.props
const items = [
@@ -62,21 +63,23 @@ class ChatConversationOptionsPopover extends ImmutablePureComponent {
title: 'Hide Conversation',
subtitle: 'Hide until next message',
onClick: () => this.handleOnHide(),
},
{
}
]
if (!isChatConversationRequest) {
items.push({
hideArrow: true,
title: isMuted ? 'Unmute Conversation' : 'Mute Conversation',
subtitle: isMuted ? null : "Don't get notified of new messages",
onClick: () => this.handleOnMute(),
},
{},
{
})
items.push({})
items.push({
hideArrow: true,
title: 'Purge messages',
subtitle: 'Remove all of your messages in this conversation',
onClick: () => this.handleOnPurge(),
},
]
})
}
return (
<PopoverLayout
@@ -125,6 +128,7 @@ ChatConversationOptionsPopover.propTypes = {
isXS: PropTypes.bool,
isPro: PropTypes.bool.isRequired,
chatConversation: ImmutablePropTypes.map,
isChatConversationRequest: PropTypes.bool,
onClosePopover: PropTypes.func.isRequired,
}

View File

@@ -16,6 +16,10 @@ import {
unbookmark,
isBookmark,
} from '../../actions/interactions';
import {
muteAccount,
unmuteAccount,
} from '../../actions/interactions';
import {
deleteStatus,
editStatus,
@@ -493,7 +497,16 @@ const mapDispatchToProps = (dispatch) => ({
accountId: account.get('id'),
}))
},
onMute(account) {
dispatch(closePopover())
if (account.getIn(['relationship', 'muting'])) {
dispatch(unmuteAccount(account.get('id')));
} else {
dispatch(openModal('MUTE', {
accountId: account.get('id'),
}))
}
},
onReport(status) {
dispatch(closePopover())
dispatch(initReport(status.get('account'), status))