Remove post reactions from vanilla flavor

This is mainly for cleanup and parity with the current PR. Not much reason to modify something that should be "vanilla" anyways.
This commit is contained in:
Essem 2023-12-18 19:42:35 -06:00
parent 59e8b9faa5
commit f84f397807
No known key found for this signature in database
GPG key ID: 7D497397CC3A2A8C
18 changed files with 3 additions and 517 deletions

View file

@ -51,16 +51,6 @@ export const UNBOOKMARK_REQUEST = 'UNBOOKMARKED_REQUEST';
export const UNBOOKMARK_SUCCESS = 'UNBOOKMARKED_SUCCESS';
export const UNBOOKMARK_FAIL = 'UNBOOKMARKED_FAIL';
export const REACTION_UPDATE = 'REACTION_UPDATE';
export const REACTION_ADD_REQUEST = 'REACTION_ADD_REQUEST';
export const REACTION_ADD_SUCCESS = 'REACTION_ADD_SUCCESS';
export const REACTION_ADD_FAIL = 'REACTION_ADD_FAIL';
export const REACTION_REMOVE_REQUEST = 'REACTION_REMOVE_REQUEST';
export const REACTION_REMOVE_SUCCESS = 'REACTION_REMOVE_SUCCESS';
export const REACTION_REMOVE_FAIL = 'REACTION_REMOVE_FAIL';
export function reblog(status, visibility) {
return function (dispatch, getState) {
dispatch(reblogRequest(status));
@ -526,75 +516,3 @@ export function unpinFail(status, error) {
skipLoading: true,
};
}
export const addReaction = (statusId, name, url) => (dispatch, getState) => {
const status = getState().get('statuses').get(statusId);
let alreadyAdded = false;
if (status) {
const reaction = status.get('reactions').find(x => x.get('name') === name);
if (reaction && reaction.get('me')) {
alreadyAdded = true;
}
}
if (!alreadyAdded) {
dispatch(addReactionRequest(statusId, name, url));
}
// encodeURIComponent is required for the Keycap Number Sign emoji, see:
// <https://github.com/glitch-soc/mastodon/pull/1980#issuecomment-1345538932>
api(getState).post(`/api/v1/statuses/${statusId}/react/${encodeURIComponent(name)}`).then(() => {
dispatch(addReactionSuccess(statusId, name));
}).catch(err => {
if (!alreadyAdded) {
dispatch(addReactionFail(statusId, name, err));
}
});
};
export const addReactionRequest = (statusId, name, url) => ({
type: REACTION_ADD_REQUEST,
id: statusId,
name,
url,
});
export const addReactionSuccess = (statusId, name) => ({
type: REACTION_ADD_SUCCESS,
id: statusId,
name,
});
export const addReactionFail = (statusId, name, error) => ({
type: REACTION_ADD_FAIL,
id: statusId,
name,
error,
});
export const removeReaction = (statusId, name) => (dispatch, getState) => {
dispatch(removeReactionRequest(statusId, name));
api(getState).post(`/api/v1/statuses/${statusId}/unreact/${encodeURIComponent(name)}`).then(() => {
dispatch(removeReactionSuccess(statusId, name));
}).catch(err => {
dispatch(removeReactionFail(statusId, name, err));
});
};
export const removeReactionRequest = (statusId, name) => ({
type: REACTION_REMOVE_REQUEST,
id: statusId,
name,
});
export const removeReactionSuccess = (statusId, name) => ({
type: REACTION_REMOVE_SUCCESS,
id: statusId,
name,
});
export const removeReactionFail = (statusId, name) => ({
type: REACTION_REMOVE_FAIL,
id: statusId,
name,
});

View file

@ -130,7 +130,6 @@ const excludeTypesFromFilter = filter => {
'follow',
'follow_request',
'favourite',
'reaction',
'reblog',
'mention',
'poll',

View file

@ -22,7 +22,7 @@ import Card from '../features/status/components/card';
// to use the progress bar to show download progress
import Bundle from '../features/ui/components/bundle';
import { MediaGallery, Video, Audio } from '../features/ui/util/async-components';
import { displayMedia, visibleReactions } from '../initial_state';
import { displayMedia } from '../initial_state';
import { Avatar } from './avatar';
import { AvatarOverlay } from './avatar_overlay';
@ -31,7 +31,6 @@ import { getHashtagBarForStatus } from './hashtag_bar';
import { RelativeTimestamp } from './relative_timestamp';
import StatusActionBar from './status_action_bar';
import StatusContent from './status_content';
import StatusReactions from './status_reactions';
import { VisibilityIcon } from './visibility_icon';
const domParser = new DOMParser();
@ -79,10 +78,6 @@ const messages = defineMessages({
class Status extends ImmutablePureComponent {
static contextTypes = {
identity: PropTypes.object,
};
static propTypes = {
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
@ -96,8 +91,6 @@ class Status extends ImmutablePureComponent {
onDelete: PropTypes.func,
onDirect: PropTypes.func,
onMention: PropTypes.func,
onReactionAdd: PropTypes.func,
onReactionRemove: PropTypes.func,
onPin: PropTypes.func,
onOpenMedia: PropTypes.func,
onOpenVideo: PropTypes.func,
@ -121,7 +114,6 @@ class Status extends ImmutablePureComponent {
cachedMediaWidth: PropTypes.number,
scrollKey: PropTypes.string,
deployPictureInPicture: PropTypes.func,
emojiMap: ImmutablePropTypes.map.isRequired,
pictureInPicture: ImmutablePropTypes.contains({
inUse: PropTypes.bool,
available: PropTypes.bool,
@ -589,15 +581,6 @@ class Status extends ImmutablePureComponent {
{expanded && hashtagBar}
<StatusReactions
statusId={status.get('id')}
reactions={status.get('reactions')}
numVisible={visibleReactions}
addReaction={this.props.onReactionAdd}
removeReaction={this.props.onReactionRemove}
canReact={this.context.identity.signedIn}
/>
<StatusActionBar scrollKey={scrollKey} status={status} account={account} onFilter={matchedFilters ? this.handleFilterClick : null} {...other} />
</div>
</div>

View file

@ -9,7 +9,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
import { ReactComponent as AddIcon } from '@material-symbols/svg-600/outlined/add.svg';
import { ReactComponent as BookmarkIcon } from '@material-symbols/svg-600/outlined/bookmark-fill.svg';
import { ReactComponent as BookmarkBorderIcon } from '@material-symbols/svg-600/outlined/bookmark.svg';
import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg';
@ -24,8 +23,7 @@ import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import DropdownMenuContainer from '../containers/dropdown_menu_container';
import EmojiPickerDropdown from '../features/compose/containers/emoji_picker_dropdown_container';
import { me, maxReactions } from '../initial_state';
import { me } from '../initial_state';
import { IconButton } from './icon_button';
@ -46,7 +44,6 @@ const messages = defineMessages({
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
favourite: { id: 'status.favourite', defaultMessage: 'Favorite' },
react: { id: 'status.react', defaultMessage: 'React' },
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
removeBookmark: { id: 'status.remove_bookmark', defaultMessage: 'Remove bookmark' },
open: { id: 'status.open', defaultMessage: 'Expand this status' },
@ -84,7 +81,6 @@ class StatusActionBar extends ImmutablePureComponent {
relationship: ImmutablePropTypes.map,
onReply: PropTypes.func,
onFavourite: PropTypes.func,
onReactionAdd: PropTypes.func,
onReblog: PropTypes.func,
onDelete: PropTypes.func,
onDirect: PropTypes.func,
@ -146,10 +142,6 @@ class StatusActionBar extends ImmutablePureComponent {
}
};
handleEmojiPick = data => {
this.props.onReactionAdd(this.props.status.get('id'), data.native.replace(/:/g, ''), data.imageUrl);
}
handleReblogClick = e => {
const { signedIn } = this.context.identity;
@ -253,8 +245,6 @@ class StatusActionBar extends ImmutablePureComponent {
this.props.onFilter();
};
handleNoOp = () => {} // hack for reaction add button
render () {
const { status, relationship, intl, withDismiss, withCounters, scrollKey } = this.props;
const { signedIn, permissions } = this.context.identity;
@ -386,28 +376,12 @@ class StatusActionBar extends ImmutablePureComponent {
);
const isReply = status.get('in_reply_to_account_id') === status.getIn(['account', 'id']);
const canReact = signedIn && status.get('reactions').filter(r => r.get('count') > 0 && r.get('me')).size < maxReactions;
const reactButton = (
<IconButton
className='status__action-bar-button'
onClick={this.handleNoOp} // EmojiPickerDropdown handles that
title={intl.formatMessage(messages.react)}
disabled={!canReact}
icon='plus'
iconComponent={AddIcon}
/>
);
return (
<div className='status__action-bar'>
<IconButton className='status__action-bar__button' title={replyTitle} icon={isReply ? 'reply' : replyIcon} iconComponent={isReply ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} counter={status.get('replies_count')} />
<IconButton className={classNames('status__action-bar__button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={RepeatIcon} onClick={this.handleReblogClick} counter={withCounters ? status.get('reblogs_count') : undefined} />
<IconButton className='status__action-bar__button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} counter={withCounters ? status.get('favourites_count') : undefined} />
{
signedIn
? <EmojiPickerDropdown className='status__action-bar-button' onPickEmoji={this.handleEmojiPick} button={reactButton} disabled={!canReact} />
: reactButton
}
<IconButton className='status__action-bar__button bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} />
{filterButton}

View file

@ -1,175 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import TransitionMotion from 'react-motion/lib/TransitionMotion';
import spring from 'react-motion/lib/spring';
import { unicodeMapping } from '../features/emoji/emoji_unicode_mapping_light';
import { autoPlayGif, reduceMotion } from '../initial_state';
import { assetHost } from '../utils/config';
import { AnimatedNumber } from './animated_number';
export default class StatusReactions extends ImmutablePureComponent {
static propTypes = {
statusId: PropTypes.string.isRequired,
reactions: ImmutablePropTypes.list.isRequired,
numVisible: PropTypes.number,
addReaction: PropTypes.func.isRequired,
canReact: PropTypes.bool.isRequired,
removeReaction: PropTypes.func.isRequired,
};
willEnter() {
return { scale: reduceMotion ? 1 : 0 };
}
willLeave() {
return { scale: reduceMotion ? 0 : spring(0, { stiffness: 170, damping: 26 }) };
}
render() {
const { reactions, numVisible } = this.props;
let visibleReactions = reactions
.filter(x => x.get('count') > 0)
.sort((a, b) => b.get('count') - a.get('count'));
if (numVisible >= 0) {
visibleReactions = visibleReactions.filter((_, i) => i < numVisible);
}
const styles = visibleReactions.map(reaction => ({
key: reaction.get('name'),
data: reaction,
style: { scale: reduceMotion ? 1 : spring(1, { stiffness: 150, damping: 13 }) },
})).toArray();
return (
<TransitionMotion styles={styles} willEnter={this.willEnter} willLeave={this.willLeave}>
{items => (
<div className={classNames('reactions-bar', { 'reactions-bar--empty': visibleReactions.isEmpty() })}>
{items.map(({ key, data, style }) => (
<Reaction
key={key}
statusId={this.props.statusId}
reaction={data}
style={{ transform: `scale(${style.scale})`, position: style.scale < 0.5 ? 'absolute' : 'static' }}
addReaction={this.props.addReaction}
removeReaction={this.props.removeReaction}
canReact={this.props.canReact}
/>
))}
</div>
)}
</TransitionMotion>
);
}
}
class Reaction extends ImmutablePureComponent {
static propTypes = {
statusId: PropTypes.string,
reaction: ImmutablePropTypes.map.isRequired,
addReaction: PropTypes.func.isRequired,
removeReaction: PropTypes.func.isRequired,
canReact: PropTypes.bool.isRequired,
style: PropTypes.object,
};
state = {
hovered: false,
};
handleClick = () => {
const { reaction, statusId, addReaction, removeReaction } = this.props;
if (reaction.get('me')) {
removeReaction(statusId, reaction.get('name'));
} else {
addReaction(statusId, reaction.get('name'));
}
}
handleMouseEnter = () => this.setState({ hovered: true })
handleMouseLeave = () => this.setState({ hovered: false })
render() {
const { reaction } = this.props;
return (
<button
className={classNames('reactions-bar__item', { active: reaction.get('me') })}
onClick={this.handleClick}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
disabled={!this.props.canReact}
style={this.props.style}
>
<span className='reactions-bar__item__emoji'>
<Emoji
hovered={this.state.hovered}
emoji={reaction.get('name')}
url={reaction.get('url')}
staticUrl={reaction.get('static_url')}
/>
</span>
<span className='reactions-bar__item__count'>
<AnimatedNumber value={reaction.get('count')} />
</span>
</button>
);
}
}
class Emoji extends React.PureComponent {
static propTypes = {
emoji: PropTypes.string.isRequired,
hovered: PropTypes.bool.isRequired,
url: PropTypes.string,
staticUrl: PropTypes.string,
};
render() {
const { emoji, hovered, url, staticUrl } = this.props;
if (unicodeMapping[emoji]) {
const { filename, shortCode } = unicodeMapping[this.props.emoji];
const title = shortCode ? `:${shortCode}:` : '';
return (
<img
draggable='false'
className='emojione'
alt={emoji}
title={title}
src={`${assetHost}/emoji/${filename}.svg`}
/>
);
} else {
const filename = (autoPlayGif || hovered) ? url : staticUrl;
const shortCode = `:${emoji}:`;
return (
<img
draggable='false'
className='emojione custom-emoji'
alt={shortCode}
title={shortCode}
src={filename}
/>
);
}
}
}

View file

@ -30,8 +30,6 @@ import {
unbookmark,
pin,
unpin,
addReaction,
removeReaction,
} from '../actions/interactions';
import { openModal } from '../actions/modal';
import { initMuteModal } from '../actions/mutes';
@ -137,14 +135,6 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
}
},
onReactionAdd (statusId, name, url) {
dispatch(addReaction(statusId, name, url));
},
onReactionRemove (statusId, name) {
dispatch(removeReaction(statusId, name));
},
onEmbed (status) {
dispatch(openModal({
modalType: 'EMBED',

View file

@ -119,17 +119,6 @@ export default class ColumnSettings extends PureComponent {
</div>
</div>
<div role='group' aria-labelledby='notifications-reaction'>
<span id='notifications-reaction' className='column-settings__section'><FormattedMessage id='notifications.column_settings.reaction' defaultMessage='Reactions:' /></span>
<div className='column-settings__pillbar'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'reaction']} onChange={onChange} label={alertStr} />
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'reaction']} onChange={this.onPushChange} label={pushStr} />}
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'reaction']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'reaction']} onChange={onChange} label={soundStr} />
</div>
</div>
<div role='group' aria-labelledby='notifications-mention'>
<span id='notifications-mention' className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span>

View file

@ -15,7 +15,6 @@ import { Icon } from 'mastodon/components/icon';
const tooltips = defineMessages({
mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' },
favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favorites' },
reactions: { id: 'notifications.filter.reactions', defaultMessage: 'Reactions' },
boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' },
polls: { id: 'notifications.filter.polls', defaultMessage: 'Poll results' },
follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' },
@ -83,13 +82,6 @@ class FilterBar extends PureComponent {
>
<Icon id='star' icon={StarIcon} />
</button>
<button
className={selectedFilter === 'reaction' ? 'active' : ''}
onClick={this.onClick('reaction')}
title={intl.formatMessage(tooltips.reactions)}
>
<Icon id='plus' fixedWidth />
</button>
<button
className={selectedFilter === 'reblog' ? 'active' : ''}
onClick={this.onClick('reblog')}

View file

@ -30,7 +30,6 @@ import Report from './report';
const messages = defineMessages({
favourite: { id: 'notification.favourite', defaultMessage: '{name} favorited your status' },
reaction: { id: 'notification.reaction', defaultMessage: '{name} reacted to your status' },
follow: { id: 'notification.follow', defaultMessage: '{name} followed you' },
ownPoll: { id: 'notification.own_poll', defaultMessage: 'Your poll has ended' },
poll: { id: 'notification.poll', defaultMessage: 'A poll you have voted in has ended' },
@ -218,38 +217,6 @@ class Notification extends ImmutablePureComponent {
);
}
renderReaction (notification, link) {
const { intl, unread } = this.props;
return (
<HotKeys handlers={this.getHandlers()}>
<div className={classNames('notification notification-reaction focusable', { unread })} tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.reaction, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
<div className='notification__message'>
<div className='notification__favourite-icon-wrapper'>
<Icon id='plus' fixedWidth />
</div>
<span title={notification.get('created_at')}>
<FormattedMessage id='notification.reaction' defaultMessage='{name} reacted to your status' values={{ name: link }} />
</span>
</div>
<StatusContainer
id={notification.get('status')}
account={notification.get('account')}
muted
withDismiss
hidden={this.props.hidden}
getScrollPosition={this.props.getScrollPosition}
updateScrollBottom={this.props.updateScrollBottom}
cachedMediaWidth={this.props.cachedMediaWidth}
cacheMediaWidth={this.props.cacheMediaWidth}
/>
</div>
</HotKeys>
);
}
renderReblog (notification, link) {
const { intl, unread } = this.props;
@ -454,8 +421,6 @@ class Notification extends ImmutablePureComponent {
return this.renderMention(notification);
case 'favourite':
return this.renderFavourite(notification, link);
case 'reaction':
return this.renderReaction(notification, link);
case 'reblog':
return this.renderReblog(notification, link);
case 'status':

View file

@ -9,7 +9,6 @@ import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
import { ReactComponent as AddIcon } from '@material-symbols/svg-600/outlined/add.svg';
import { ReactComponent as BookmarkIcon } from '@material-symbols/svg-600/outlined/bookmark-fill.svg';
import { ReactComponent as BookmarkBorderIcon } from '@material-symbols/svg-600/outlined/bookmark.svg';
import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg';
@ -22,11 +21,9 @@ import { ReactComponent as StarBorderIcon } from '@material-symbols/svg-600/outl
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import { IconButton } from '../../../components/icon_button';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
import { me, maxReactions } from '../../../initial_state';
import EmojiPickerDropdown from '../../compose/containers/emoji_picker_dropdown_container';
import { me } from '../../../initial_state';
const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' },
@ -40,7 +37,6 @@ const messages = defineMessages({
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
favourite: { id: 'status.favourite', defaultMessage: 'Favorite' },
react: { id: 'status.react', defaultMessage: 'React' },
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
more: { id: 'status.more', defaultMessage: 'More' },
mute: { id: 'status.mute', defaultMessage: 'Mute @{name}' },
@ -79,7 +75,6 @@ class ActionBar extends PureComponent {
onReply: PropTypes.func.isRequired,
onReblog: PropTypes.func.isRequired,
onFavourite: PropTypes.func.isRequired,
onReactionAdd: PropTypes.func.isRequired,
onBookmark: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
onEdit: PropTypes.func.isRequired,
@ -111,10 +106,6 @@ class ActionBar extends PureComponent {
this.props.onFavourite(this.props.status);
};
handleEmojiPick = data => {
this.props.onReactionAdd(this.props.status.get('id'), data.native.replace(/:/g, ''));
};
handleBookmarkClick = (e) => {
this.props.onBookmark(this.props.status, e);
};
@ -202,8 +193,6 @@ class ActionBar extends PureComponent {
navigator.clipboard.writeText(url);
};
handleNoOp = () => {}; // hack for reaction add button
render () {
const { status, relationship, intl } = this.props;
const { signedIn, permissions } = this.context.identity;
@ -289,18 +278,6 @@ class ActionBar extends PureComponent {
}
}
const canReact = signedIn && status.get('reactions').filter(r => r.get('count') > 0 && r.get('me')).size < maxReactions;
const reactButton = (
<IconButton
className='plus-icon'
onClick={this.handleNoOp} // EmojiPickerDropdown handles that
title={intl.formatMessage(messages.react)}
disabled={!canReact}
icon='plus'
iconComponent={AddIcon}
/>
);
let replyIcon;
let replyIconComponent;
if (status.get('in_reply_to_id', null) === null) {
@ -329,13 +306,6 @@ class ActionBar extends PureComponent {
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} iconComponent={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} /></div>
<div className='detailed-status__button'><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={RepeatIcon} onClick={this.handleReblogClick} /></div>
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} /></div>
<div className='detailed-status__button'>
{
canReact
? <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={reactButton} disabled={!canReact} />
: reactButton
}
</div>
<div className='detailed-status__button'><IconButton className='bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} /></div>
<div className='detailed-status__action-bar-dropdown'>

View file

@ -17,7 +17,6 @@ import EditedTimestamp from 'mastodon/components/edited_timestamp';
import { getHashtagBarForStatus } from 'mastodon/components/hashtag_bar';
import { Icon } from 'mastodon/components/icon';
import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder';
import StatusReactions from 'mastodon/components/status_reactions';
import { VisibilityIcon } from 'mastodon/components/visibility_icon';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
@ -33,10 +32,6 @@ import Card from './card';
class DetailedStatus extends ImmutablePureComponent {
static contextTypes = {
identity: PropTypes.object,
};
static propTypes = {
status: ImmutablePropTypes.map,
onOpenMedia: PropTypes.func.isRequired,
@ -53,8 +48,6 @@ class DetailedStatus extends ImmutablePureComponent {
available: PropTypes.bool,
}),
onToggleMediaVisibility: PropTypes.func,
onReactionAdd: PropTypes.func.isRequired,
onReactionRemove: PropTypes.func.isRequired,
...WithRouterPropTypes,
};
@ -317,14 +310,6 @@ class DetailedStatus extends ImmutablePureComponent {
{expanded && hashtagBar}
<StatusReactions
statusId={status.get('id')}
reactions={status.get('reactions')}
addReaction={this.props.onReactionAdd}
removeReaction={this.props.onReactionRemove}
canReact={this.context.identity.signedIn}
/>
<div className='detailed-status__meta'>
<a className='detailed-status__datetime' href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} 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' />

View file

@ -46,8 +46,6 @@ import {
unreblog,
pin,
unpin,
addReaction,
removeReaction,
} from '../../actions/interactions';
import { openModal } from '../../actions/modal';
import { initMuteModal } from '../../actions/mutes';
@ -267,19 +265,6 @@ class Status extends ImmutablePureComponent {
}
};
handleReactionAdd = (statusId, name, url) => {
const { dispatch } = this.props;
const { signedIn } = this.context.identity;
if (signedIn) {
dispatch(addReaction(statusId, name, url));
}
};
handleReactionRemove = (statusId, name) => {
this.props.dispatch(removeReaction(statusId, name));
};
handlePin = (status) => {
if (status.get('pinned')) {
this.props.dispatch(unpin(status));
@ -717,15 +702,12 @@ class Status extends ImmutablePureComponent {
status={status}
onOpenVideo={this.handleOpenVideo}
onOpenMedia={this.handleOpenMedia}
onReactionAdd={this.handleReactionAdd}
onReactionRemove={this.handleReactionRemove}
onToggleHidden={this.handleToggleHidden}
onTranslate={this.handleTranslate}
domain={domain}
showMedia={this.state.showMedia}
onToggleMediaVisibility={this.handleToggleMediaVisibility}
pictureInPicture={pictureInPicture}
emojiMap={this.props.emojiMap}
/>
<ActionBar
@ -733,7 +715,6 @@ class Status extends ImmutablePureComponent {
status={status}
onReply={this.handleReplyClick}
onFavourite={this.handleFavouriteClick}
onReactionAdd={this.handleReactionAdd}
onReblog={this.handleReblogClick}
onBookmark={this.handleBookmarkClick}
onDelete={this.handleDeleteClick}

View file

@ -22,7 +22,6 @@
* @property {boolean} limited_federation_mode
* @property {string} locale
* @property {string | null} mascot
* @property {number} max_reactions
* @property {string=} me
* @property {string=} moved_to_account_id
* @property {string=} owner
@ -43,7 +42,6 @@
* @property {boolean} use_blurhash
* @property {boolean=} use_pending_items
* @property {string} version
* @property {number} visible_reactions
* @property {string} sso_redirect
*/
@ -54,7 +52,6 @@
* @property {boolean=} critical_updates_pending
* @property {InitialStateMeta} meta
* @property {number} max_toot_chars
* @property {number} max_reactions
*/
const element = document.getElementById('initial-state');
@ -88,7 +85,6 @@ export const expandSpoilers = getMeta('expand_spoilers');
export const forceSingleColumn = !getMeta('advanced_layout');
export const limitedFederationMode = getMeta('limited_federation_mode');
export const mascot = getMeta('mascot');
export const maxReactions = (initialState && initialState.max_reactions) || 1;
export const me = getMeta('me');
export const movedToAccountId = getMeta('moved_to_account_id');
export const owner = getMeta('owner');
@ -108,7 +104,6 @@ export const unfollowModal = getMeta('unfollow_modal');
export const useBlurhash = getMeta('use_blurhash');
export const usePendingItems = getMeta('use_pending_items');
export const version = getMeta('version');
export const visibleReactions = getMeta('visible_reactions');
export const languages = initialState?.languages;
export const criticalUpdatesPending = initialState?.critical_updates_pending;
// @ts-expect-error

View file

@ -425,7 +425,6 @@
"notification.admin.report": "{name} meldete {target}",
"notification.admin.sign_up": "{name} registrierte sich",
"notification.favourite": "{name} favorisierte deinen Beitrag",
"notification.reaction": "{name} hat auf deinen Beitrag reagiert",
"notification.follow": "{name} folgt dir",
"notification.follow_request": "{name} möchte dir folgen",
"notification.mention": "{name} erwähnte dich",
@ -440,7 +439,6 @@
"notifications.column_settings.admin.sign_up": "Neue Registrierungen:",
"notifications.column_settings.alert": "Desktop-Benachrichtigungen",
"notifications.column_settings.favourite": "Favoriten:",
"notifications.column_settings.reaction": "Reaktionen:",
"notifications.column_settings.filter_bar.advanced": "Alle Filterkategorien anzeigen",
"notifications.column_settings.filter_bar.category": "Filterleiste:",
"notifications.column_settings.filter_bar.show_bar": "Filterleiste anzeigen",
@ -633,7 +631,6 @@
"status.edited_x_times": "{count, plural, one {{count}-mal} other {{count}-mal}} bearbeitet",
"status.embed": "Beitrag per iFrame einbetten",
"status.favourite": "Favorisieren",
"status.react": "Reagieren",
"status.filter": "Beitrag filtern",
"status.filtered": "Gefiltert",
"status.hide": "Beitrag ausblenden",
@ -691,7 +688,6 @@
"timeline_hint.resources.statuses": "Ältere Beiträge",
"trends.counter_by_accounts": "{count, plural, one {{counter} Profil} other {{counter} Profile}} {days, plural, one {seit gestern} other {in {days} Tagen}}",
"trends.trending_now": "Aktuelle Trends",
"tooltips.reactions": "Reaktionen",
"ui.beforeunload": "Dein Entwurf geht verloren, wenn du Mastodon verlässt.",
"units.short.billion": "{count} Mrd.",
"units.short.million": "{count} Mio.",

View file

@ -425,7 +425,6 @@
"notification.admin.report": "{name} reported {target}",
"notification.admin.sign_up": "{name} signed up",
"notification.favourite": "{name} favorited your post",
"notification.reaction": "{name} reacted to your post",
"notification.follow": "{name} followed you",
"notification.follow_request": "{name} has requested to follow you",
"notification.mention": "{name} mentioned you",
@ -440,7 +439,6 @@
"notifications.column_settings.admin.sign_up": "New sign-ups:",
"notifications.column_settings.alert": "Desktop notifications",
"notifications.column_settings.favourite": "Favorites:",
"notifications.column_settings.reaction": "Reactions:",
"notifications.column_settings.filter_bar.advanced": "Display all categories",
"notifications.column_settings.filter_bar.category": "Quick filter bar",
"notifications.column_settings.filter_bar.show_bar": "Show filter bar",
@ -633,7 +631,6 @@
"status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}",
"status.embed": "Embed",
"status.favourite": "Favorite",
"status.react": "React",
"status.filter": "Filter this post",
"status.filtered": "Filtered",
"status.hide": "Hide post",
@ -691,7 +688,6 @@
"timeline_hint.resources.statuses": "Older posts",
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {{days} days}}",
"trends.trending_now": "Trending now",
"tooltips.reactions": "Reactions",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"units.short.billion": "{count}B",
"units.short.million": "{count}M",

View file

@ -34,7 +34,6 @@ const initialState = ImmutableMap({
follow: false,
follow_request: false,
favourite: false,
reaction: false,
reblog: false,
mention: false,
poll: false,
@ -58,7 +57,6 @@ const initialState = ImmutableMap({
follow_request: false,
favourite: true,
reblog: true,
reaction: true,
mention: true,
poll: true,
status: true,
@ -72,7 +70,6 @@ const initialState = ImmutableMap({
follow_request: false,
favourite: true,
reblog: true,
reaction: true,
mention: true,
poll: true,
status: true,

View file

@ -13,11 +13,6 @@ import {
UNFAVOURITE_FAIL,
BOOKMARK_REQUEST,
BOOKMARK_FAIL,
REACTION_UPDATE,
REACTION_ADD_FAIL,
REACTION_REMOVE_FAIL,
REACTION_ADD_REQUEST,
REACTION_REMOVE_REQUEST,
UNBOOKMARK_REQUEST,
UNBOOKMARK_FAIL,
} from '../actions/interactions';
@ -47,43 +42,6 @@ const deleteStatus = (state, id, references) => {
return state.delete(id);
};
const updateReaction = (state, id, name, updater) => state.update(
id,
status => status.update(
'reactions',
reactions => {
const index = reactions.findIndex(reaction => reaction.get('name') === name);
if (index > -1) {
return reactions.update(index, reaction => updater(reaction));
} else {
return reactions.push(updater(fromJS({ name, count: 0 })));
}
},
),
);
const updateReactionCount = (state, reaction) => updateReaction(state, reaction.status_id, reaction.name, x => x.set('count', reaction.count));
// The url parameter is only used when adding a new custom emoji reaction
// (one that wasn't in the reactions list before) because we don't have its
// URL yet. In all other cases, it's undefined.
const addReaction = (state, id, name, url) => updateReaction(
state,
id,
name,
x => x.set('me', true)
.update('count', n => n + 1)
.update('url', old => old ? old : url)
.update('static_url', old => old ? old : url),
);
const removeReaction = (state, id, name) => updateReaction(
state,
id,
name,
x => x.set('me', false).update('count', n => n - 1),
);
const statusTranslateSuccess = (state, id, translation) => {
return state.withMutations(map => {
map.setIn([id, 'translation'], fromJS(normalizeStatusTranslation(translation, map.get(id))));
@ -137,14 +95,6 @@ export default function statuses(state = initialState, action) {
return state.setIn([action.status.get('id'), 'reblogged'], true);
case REBLOG_FAIL:
return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], false);
case REACTION_UPDATE:
return updateReactionCount(state, action.reaction);
case REACTION_ADD_REQUEST:
case REACTION_REMOVE_FAIL:
return addReaction(state, action.id, action.name, action.url);
case REACTION_REMOVE_REQUEST:
case REACTION_ADD_FAIL:
return removeReaction(state, action.id, action.name);
case UNREBLOG_REQUEST:
return state.setIn([action.status.get('id'), 'reblogged'], false);
case UNREBLOG_FAIL:

View file

@ -1125,7 +1125,6 @@ body > [data-popper-placement] {
.status__content,
.status__action-bar,
.reactions-bar,
.media-gallery,
.video-player,
.audio-player,
@ -1179,10 +1178,6 @@ body > [data-popper-placement] {
}
}
}
.reactions-bar--empty {
margin-top: 0;
}
}
.status__relative-time {
@ -1324,16 +1319,6 @@ body > [data-popper-placement] {
align-items: center;
gap: 18px;
margin-top: 16px;
& > .emoji-picker-dropdown > .emoji-button {
padding: 0;
}
}
.status__action-bar-button {
.fa-plus {
padding-top: 1px;
}
}
.detailed-status__action-bar-dropdown {
@ -4291,10 +4276,6 @@ a.status-card {
text-align: center;
}
.detailed-status__button .emoji-button {
padding: 0;
}
.column-settings__outer {
background: lighten($ui-base-color, 8%);
padding: 15px;