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:
parent
59e8b9faa5
commit
f84f397807
18 changed files with 3 additions and 517 deletions
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -130,7 +130,6 @@ const excludeTypesFromFilter = filter => {
|
|||
'follow',
|
||||
'follow_request',
|
||||
'favourite',
|
||||
'reaction',
|
||||
'reblog',
|
||||
'mention',
|
||||
'poll',
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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',
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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')}
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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'>
|
||||
|
|
|
@ -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' />
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue