forked from mirrors/catstodon
move react button to action bar
This commit is contained in:
parent
19491d2032
commit
da78479b93
8 changed files with 58 additions and 8 deletions
|
@ -5,11 +5,12 @@ import IconButton from './icon_button';
|
|||
import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { me } from 'flavours/glitch/initial_state';
|
||||
import { me, maxReactions } from 'flavours/glitch/initial_state';
|
||||
import RelativeTimestamp from './relative_timestamp';
|
||||
import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
|
||||
import classNames from 'classnames';
|
||||
import { PERMISSION_MANAGE_USERS } from 'flavours/glitch/permissions';
|
||||
import EmojiPickerDropdown from '../features/compose/containers/emoji_picker_dropdown_container';
|
||||
|
||||
const messages = defineMessages({
|
||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
||||
|
@ -28,6 +29,7 @@ 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: 'Favourite' },
|
||||
react: { id: 'status.react', defaultMessage: 'React' },
|
||||
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
|
||||
open: { id: 'status.open', defaultMessage: 'Expand this status' },
|
||||
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
|
||||
|
@ -114,6 +116,16 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
handleEmojiPick = data => {
|
||||
const { signedIn } = this.context.identity;
|
||||
|
||||
if (signedIn) {
|
||||
this.props.onReactionAdd(this.props.status.get('id'), data.native.replace(/:/g, ''));
|
||||
} else {
|
||||
this.props.onInteractionModal('favourite', this.props.status);
|
||||
}
|
||||
}
|
||||
|
||||
handleReblogClick = e => {
|
||||
const { signedIn } = this.context.identity;
|
||||
|
||||
|
@ -195,6 +207,8 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
this.props.onAddFilter(this.props.status);
|
||||
}
|
||||
|
||||
nop = () => {}
|
||||
|
||||
render () {
|
||||
const { status, intl, withDismiss, withCounters, showReplyCount, scrollKey } = this.props;
|
||||
|
||||
|
@ -298,6 +312,17 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
<IconButton className='status__action-bar-button' title={intl.formatMessage(messages.hide)} icon='eye' onClick={this.handleHideClick} />
|
||||
);
|
||||
|
||||
const canReact = status.get('reactions').filter(r => r.get('count') > 0 && r.get('me')).size < maxReactions;
|
||||
const reactButton = (
|
||||
<IconButton
|
||||
className='status__action-bar-button'
|
||||
onClick={this.nop} // EmojiPickerDropdown handles that
|
||||
title={intl.formatMessage(messages.react)}
|
||||
disabled={!canReact}
|
||||
icon='plus'
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className='status__action-bar'>
|
||||
<IconButton
|
||||
|
@ -310,6 +335,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
/>
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon={reblogIcon} 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' onClick={this.handleFavouriteClick} counter={withCounters ? status.get('favourites_count') : undefined} />
|
||||
<EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={reactButton} disabled={!canReact} />
|
||||
{shareButton}
|
||||
<IconButton className='status__action-bar-button bookmark-icon' disabled={anonymousAccess} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} />
|
||||
|
||||
|
|
|
@ -5,13 +5,11 @@ import { reduceMotion } from '../initial_state';
|
|||
import spring from 'react-motion/lib/spring';
|
||||
import TransitionMotion from 'react-motion/lib/TransitionMotion';
|
||||
import classNames from 'classnames';
|
||||
import EmojiPickerDropdown from '../features/compose/containers/emoji_picker_dropdown_container';
|
||||
import Icon from './icon';
|
||||
import React from 'react';
|
||||
import unicodeMapping from '../features/emoji/emoji_unicode_mapping_light';
|
||||
import AnimatedNumber from './animated_number';
|
||||
import { assetHost } from '../utils/config';
|
||||
import { autoPlayGif, maxReactions } from '../initial_state';
|
||||
import { autoPlayGif } from '../initial_state';
|
||||
|
||||
export default class StatusReactionsBar extends ImmutablePureComponent {
|
||||
|
||||
|
@ -61,8 +59,6 @@ export default class StatusReactionsBar extends ImmutablePureComponent {
|
|||
emojiMap={this.props.emojiMap}
|
||||
/>
|
||||
))}
|
||||
|
||||
{visibleReactions.size < maxReactions && <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={<Icon id='plus' />} />}
|
||||
</div>
|
||||
)}
|
||||
</TransitionMotion>
|
||||
|
|
|
@ -321,6 +321,7 @@ class EmojiPickerDropdown extends React.PureComponent {
|
|||
onSkinTone: PropTypes.func.isRequired,
|
||||
skinTone: PropTypes.number.isRequired,
|
||||
button: PropTypes.node,
|
||||
disabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
|
@ -358,7 +359,7 @@ class EmojiPickerDropdown extends React.PureComponent {
|
|||
}
|
||||
|
||||
onToggle = (e) => {
|
||||
if (!this.state.loading && (!e.key || e.key === 'Enter')) {
|
||||
if (!this.state.disabled && !this.state.loading && (!e.key || e.key === 'Enter')) {
|
||||
if (this.state.active) {
|
||||
this.onHideDropdown();
|
||||
} else {
|
||||
|
|
|
@ -4,10 +4,11 @@ import IconButton from 'flavours/glitch/components/icon_button';
|
|||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { me } from 'flavours/glitch/initial_state';
|
||||
import { me, maxReactions } from 'flavours/glitch/initial_state';
|
||||
import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
|
||||
import classNames from 'classnames';
|
||||
import { PERMISSION_MANAGE_USERS } from 'flavours/glitch/permissions';
|
||||
import EmojiPickerDropdown from '../../compose/containers/emoji_picker_dropdown_container';
|
||||
|
||||
const messages = defineMessages({
|
||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
||||
|
@ -21,6 +22,7 @@ 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: 'Favourite' },
|
||||
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}' },
|
||||
|
@ -51,6 +53,7 @@ class ActionBar extends React.PureComponent {
|
|||
onReply: PropTypes.func.isRequired,
|
||||
onReblog: PropTypes.func.isRequired,
|
||||
onFavourite: PropTypes.func.isRequired,
|
||||
onReactionAdd: PropTypes.func.isRequired,
|
||||
onBookmark: PropTypes.func.isRequired,
|
||||
onMute: PropTypes.func,
|
||||
onMuteConversation: PropTypes.func,
|
||||
|
@ -77,6 +80,10 @@ class ActionBar extends React.PureComponent {
|
|||
this.props.onFavourite(this.props.status, e);
|
||||
}
|
||||
|
||||
handleEmojiPick = data => {
|
||||
this.props.onReactionAdd(this.props.status.get('id'), data.native.replace(/:/g, ''));
|
||||
}
|
||||
|
||||
handleBookmarkClick = (e) => {
|
||||
this.props.onBookmark(this.props.status, e);
|
||||
}
|
||||
|
@ -137,6 +144,8 @@ class ActionBar extends React.PureComponent {
|
|||
navigator.clipboard.writeText(url);
|
||||
}
|
||||
|
||||
nop = () => {}
|
||||
|
||||
render () {
|
||||
const { status, intl } = this.props;
|
||||
const { signedIn, permissions } = this.context.identity;
|
||||
|
@ -194,6 +203,17 @@ class ActionBar extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
const canReact = status.get('reactions').filter(r => r.get('count') > 0 && r.get('me')).size < maxReactions;
|
||||
const reactButton = (
|
||||
<IconButton
|
||||
className='plus-icon'
|
||||
onClick={this.nop} // EmojiPickerDropdown handles that
|
||||
title={intl.formatMessage(messages.react)}
|
||||
disabled={!canReact}
|
||||
icon='plus'
|
||||
/>
|
||||
);
|
||||
|
||||
const shareButton = ('share' in navigator) && publicStatus && (
|
||||
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.share)} icon='share-alt' onClick={this.handleShare} /></div>
|
||||
);
|
||||
|
@ -216,6 +236,7 @@ class ActionBar extends React.PureComponent {
|
|||
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_id', null) === null ? 'reply' : 'reply-all'} onClick={this.handleReplyClick} /></div>
|
||||
<div className='detailed-status__button'><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' 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' onClick={this.handleFavouriteClick} /></div>
|
||||
<div className='detailed-status__button'><EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={reactButton} disabled={!canReact} /></div>
|
||||
{shareButton}
|
||||
<div className='detailed-status__button'><IconButton className='bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} /></div>
|
||||
|
||||
|
|
|
@ -721,6 +721,7 @@ class Status extends ImmutablePureComponent {
|
|||
status={status}
|
||||
onReply={this.handleReplyClick}
|
||||
onFavourite={this.handleFavouriteClick}
|
||||
onReactionAdd={this.handleReactionAdd}
|
||||
onReblog={this.handleReblogClick}
|
||||
onBookmark={this.handleBookmarkClick}
|
||||
onDelete={this.handleDeleteClick}
|
||||
|
|
|
@ -5,6 +5,8 @@ const messages = {
|
|||
'notifications.column_settings.reaction': 'Reaktionen:',
|
||||
|
||||
'tooltips.reactions': 'Reaktionen',
|
||||
|
||||
'status.react': 'Reagieren',
|
||||
};
|
||||
|
||||
export default Object.assign({}, inherited, messages);
|
||||
|
|
|
@ -115,6 +115,7 @@ const messages = {
|
|||
'settings.wide_view_hint': 'Stretches columns to better fill the available space.',
|
||||
'settings.navbar_under': 'Navbar at the bottom (Mobile only)',
|
||||
'status.collapse': 'Collapse',
|
||||
'status.react': 'React',
|
||||
'status.uncollapse': 'Uncollapse',
|
||||
'status.in_reply_to': 'This toot is a reply',
|
||||
'status.has_preview_card': 'Features an attached preview card',
|
||||
|
|
|
@ -5,6 +5,8 @@ const messages = {
|
|||
'notifications.column_settings.reaction': 'Réactions:',
|
||||
|
||||
'tooltips.reactions': 'Réactions',
|
||||
|
||||
'status.react': 'Réagir',
|
||||
};
|
||||
|
||||
export default Object.assign({}, inherited, messages);
|
||||
|
|
Loading…
Reference in a new issue