kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Favourites: display favourites for Mastodon (if exposableReactions is manually toggled)
rodzic
82dd1d16c8
commit
891a65b66f
|
@ -458,7 +458,13 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
emoji={meEmojiReact}
|
emoji={meEmojiReact}
|
||||||
onClick={this.handleLikeButtonClick}
|
onClick={this.handleLikeButtonClick}
|
||||||
/>
|
/>
|
||||||
{emojiReactCount !== 0 && <span className='detailed-status__link'>{emojiReactCount}</span>}
|
{emojiReactCount !== 0 && (
|
||||||
|
(features.exposableReactions && !features.emojiReacts) ? (
|
||||||
|
<Link to={`/@${status.getIn(['account', 'acct'])}/posts/${status.get('id')}/likes`} className='detailed-status__link'>{emojiReactCount}</Link>
|
||||||
|
) : (
|
||||||
|
<span className='detailed-status__link'>{emojiReactCount}</span>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{shareButton}
|
{shareButton}
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,25 @@ import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
import { fetchFavourites } from '../../actions/interactions';
|
import { fetchFavourites } from '../../actions/interactions';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { injectIntl, defineMessages, FormattedMessage } from 'react-intl';
|
||||||
import AccountContainer from '../../containers/account_container';
|
import AccountContainer from '../../containers/account_container';
|
||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
import ScrollableList from '../../components/scrollable_list';
|
import ScrollableList from '../../components/scrollable_list';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
heading: { id: 'column.favourites', defaultMessage: 'Likes' },
|
||||||
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]),
|
accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @connect(mapStateToProps)
|
export default @connect(mapStateToProps)
|
||||||
|
@injectIntl
|
||||||
class Favourites extends ImmutablePureComponent {
|
class Favourites extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
accountIds: ImmutablePropTypes.orderedSet,
|
accountIds: ImmutablePropTypes.orderedSet,
|
||||||
|
@ -37,7 +43,7 @@ class Favourites extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { accountIds } = this.props;
|
const { intl, accountIds } = this.props;
|
||||||
|
|
||||||
if (!accountIds) {
|
if (!accountIds) {
|
||||||
return (
|
return (
|
||||||
|
@ -50,7 +56,7 @@ class Favourites extends ImmutablePureComponent {
|
||||||
const emptyMessage = <FormattedMessage id='empty_column.favourites' defaultMessage='No one has liked this post yet. When someone does, they will show up here.' />;
|
const emptyMessage = <FormattedMessage id='empty_column.favourites' defaultMessage='No one has liked this post yet. When someone does, they will show up here.' />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column>
|
<Column heading={intl.formatMessage(messages.heading)}>
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
scrollKey='favourites'
|
scrollKey='favourites'
|
||||||
emptyMessage={emptyMessage}
|
emptyMessage={emptyMessage}
|
||||||
|
|
|
@ -14,11 +14,10 @@ import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const instance = state.get('instance');
|
const instance = state.get('instance');
|
||||||
const features = getFeatures(instance);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
allowedEmoji: getSoapboxConfig(state).get('allowedEmoji'),
|
allowedEmoji: getSoapboxConfig(state).get('allowedEmoji'),
|
||||||
reactionList: features.exposableReactions,
|
features: getFeatures(instance),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ class StatusInteractionBar extends ImmutablePureComponent {
|
||||||
status: ImmutablePropTypes.map,
|
status: ImmutablePropTypes.map,
|
||||||
me: SoapboxPropTypes.me,
|
me: SoapboxPropTypes.me,
|
||||||
allowedEmoji: ImmutablePropTypes.list,
|
allowedEmoji: ImmutablePropTypes.list,
|
||||||
reactionList: PropTypes.bool,
|
features: PropTypes.object.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
getNormalizedReacts = () => {
|
getNormalizedReacts = () => {
|
||||||
|
@ -42,7 +41,7 @@ class StatusInteractionBar extends ImmutablePureComponent {
|
||||||
).reverse();
|
).reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
getRepost = () => {
|
getReposts = () => {
|
||||||
const { status } = this.props;
|
const { status } = this.props;
|
||||||
if (status.get('reblogs_count')) {
|
if (status.get('reblogs_count')) {
|
||||||
return (
|
return (
|
||||||
|
@ -58,8 +57,39 @@ class StatusInteractionBar extends ImmutablePureComponent {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFavourites = () => {
|
||||||
|
const { features, status } = this.props;
|
||||||
|
|
||||||
|
if (status.get('favourites_count')) {
|
||||||
|
const favourites = (
|
||||||
|
<>
|
||||||
|
<Icon src={require('@tabler/icons/icons/thumb-up.svg')} />
|
||||||
|
<span className='emoji-reacts__count'>
|
||||||
|
<FormattedNumber value={status.get('favourites_count')} />
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (features.exposableReactions) {
|
||||||
|
return (
|
||||||
|
<Link to={`/@${status.getIn(['account', 'acct'])}/posts/${status.get('id')}/likes`} className='emoji-react emoji-react--favourites'>
|
||||||
|
{favourites}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div className='emoji-react emoji-react--favourites'>
|
||||||
|
{favourites}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
getEmojiReacts = () => {
|
getEmojiReacts = () => {
|
||||||
const { status, reactionList } = this.props;
|
const { status, features } = this.props;
|
||||||
|
|
||||||
const emojiReacts = this.getNormalizedReacts();
|
const emojiReacts = this.getNormalizedReacts();
|
||||||
const count = emojiReacts.reduce((acc, cur) => (
|
const count = emojiReacts.reduce((acc, cur) => (
|
||||||
|
@ -81,7 +111,7 @@ class StatusInteractionBar extends ImmutablePureComponent {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (reactionList) {
|
if (features.exposableReactions) {
|
||||||
return <Link to={`/@${status.getIn(['account', 'acct'])}/posts/${status.get('id')}/reactions/${e.get('name')}`} className='emoji-react' key={i}>{emojiReact}</Link>;
|
return <Link to={`/@${status.getIn(['account', 'acct'])}/posts/${status.get('id')}/reactions/${e.get('name')}`} className='emoji-react' key={i}>{emojiReact}</Link>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,13 +129,12 @@ class StatusInteractionBar extends ImmutablePureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const emojiReacts = this.getEmojiReacts();
|
const { features } = this.props;
|
||||||
const repost = this.getRepost();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='status-interaction-bar'>
|
<div className='status-interaction-bar'>
|
||||||
{emojiReacts}
|
{features.emojiReacts ? this.getEmojiReacts() : this.getFavourites()}
|
||||||
{repost}
|
{this.getReposts()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ import {
|
||||||
Following,
|
Following,
|
||||||
Reblogs,
|
Reblogs,
|
||||||
Reactions,
|
Reactions,
|
||||||
// Favourites,
|
Favourites,
|
||||||
DirectTimeline,
|
DirectTimeline,
|
||||||
Conversations,
|
Conversations,
|
||||||
HashtagTimeline,
|
HashtagTimeline,
|
||||||
|
@ -288,6 +288,7 @@ class SwitchingColumnsArea extends React.PureComponent {
|
||||||
<WrappedRoute path='/@:username/pins' component={PinnedStatuses} page={ProfilePage} content={children} />
|
<WrappedRoute path='/@:username/pins' component={PinnedStatuses} page={ProfilePage} content={children} />
|
||||||
<WrappedRoute path='/@:username/posts/:statusId' publicRoute exact page={StatusPage} component={Status} content={children} />
|
<WrappedRoute path='/@:username/posts/:statusId' publicRoute exact page={StatusPage} component={Status} content={children} />
|
||||||
<WrappedRoute path='/@:username/posts/:statusId/reblogs' page={DefaultPage} component={Reblogs} content={children} />
|
<WrappedRoute path='/@:username/posts/:statusId/reblogs' page={DefaultPage} component={Reblogs} content={children} />
|
||||||
|
<WrappedRoute path='/@:username/posts/:statusId/likes' page={DefaultPage} component={Favourites} content={children} />
|
||||||
<WrappedRoute path='/@:username/posts/:statusId/reactions/:reaction?' page={DefaultPage} component={Reactions} content={children} />
|
<WrappedRoute path='/@:username/posts/:statusId/reactions/:reaction?' page={DefaultPage} component={Reactions} content={children} />
|
||||||
<Redirect from='/@:username/:statusId' to='/@:username/posts/:statusId' />
|
<Redirect from='/@:username/:statusId' to='/@:username/posts/:statusId' />
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
|
|
||||||
.detailed-status__link {
|
.detailed-status__link {
|
||||||
color: var(--primary-text-color--faint);
|
color: var(--primary-text-color--faint);
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,12 +21,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-react--reblogs {
|
.emoji-react--reblogs,
|
||||||
|
.emoji-react--favourites {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
margin-right: 0.2em;
|
margin-right: 0.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-react--reblogs {
|
||||||
|
.svg-icon {
|
||||||
color: var(--highlight-text-color);
|
color: var(--highlight-text-color);
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
|
@ -35,6 +42,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.emoji-react--favourites {
|
||||||
|
.svg-icon {
|
||||||
|
color: $gold-star;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.emoji-reacts {
|
.emoji-reacts {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
|
|
Ładowanie…
Reference in New Issue