mirror of
https://framagit.org/tykayn/mastodon.git
synced 2023-08-25 08:33:12 +02:00
icons for dropdown
This commit is contained in:
parent
32dbed3864
commit
6497665819
BIN
app/javascript/images/logo_cipherbliss.png
Executable file
BIN
app/javascript/images/logo_cipherbliss.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@ -128,11 +128,13 @@ class DropdownMenu extends React.PureComponent {
|
||||
return <li key={`sep-${i}`} className='dropdown-menu__separator' />;
|
||||
}
|
||||
|
||||
const { text, href = '#', target = '_blank', method } = option;
|
||||
const { text, href = '#', target = '_blank', method, iconName } = option;
|
||||
|
||||
return (
|
||||
<li className='dropdown-menu__item' key={`${text}-${i}`}>
|
||||
<a href={href} target={target} data-method={method} rel='noopener noreferrer' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}>
|
||||
|
||||
<i className={'fa fa-'+iconName} />
|
||||
{text}
|
||||
</a>
|
||||
</li>
|
||||
|
@ -120,7 +120,7 @@ export default class IconButton extends React.PureComponent {
|
||||
});
|
||||
|
||||
if (typeof counter !== 'undefined') {
|
||||
style.width = 'auto';
|
||||
style.width = '100%';
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -6,41 +6,41 @@ import IconButton from './icon_button';
|
||||
import DropdownMenuContainer from '../containers/dropdown_menu_container';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { me, isStaff } from '../initial_state';
|
||||
import { isStaff, me } from '../initial_state';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const messages = defineMessages({
|
||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
||||
redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' },
|
||||
direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' },
|
||||
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
|
||||
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
||||
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
|
||||
reply: { id: 'status.reply', defaultMessage: 'Reply' },
|
||||
share: { id: 'status.share', defaultMessage: 'Share' },
|
||||
more: { id: 'status.more', defaultMessage: 'More' },
|
||||
replyAll: { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
|
||||
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
|
||||
reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' },
|
||||
delete : { id: 'status.delete', defaultMessage: 'Delete' },
|
||||
redraft : { id: 'status.redraft', defaultMessage: 'Delete & re-draft' },
|
||||
direct : { id: 'status.direct', defaultMessage: 'Direct message @{name}' },
|
||||
mention : { id: 'status.mention', defaultMessage: 'Mention @{name}' },
|
||||
mute : { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
||||
block : { id: 'account.block', defaultMessage: 'Block @{name}' },
|
||||
reply : { id: 'status.reply', defaultMessage: 'Reply' },
|
||||
share : { id: 'status.share', defaultMessage: 'Share' },
|
||||
more : { id: 'status.more', defaultMessage: 'More' },
|
||||
replyAll : { id: 'status.replyAll', defaultMessage: 'Reply to thread' },
|
||||
reblog : { id: 'status.reblog', defaultMessage: 'Boost' },
|
||||
reblog_private : { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' },
|
||||
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' },
|
||||
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
|
||||
removeBookmark: { id: 'status.remove_bookmark', defaultMessage: 'Remove bookmark' },
|
||||
open: { id: 'status.open', defaultMessage: 'Expand this status' },
|
||||
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
|
||||
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
||||
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
||||
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
|
||||
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
|
||||
embed: { id: 'status.embed', defaultMessage: 'Embed' },
|
||||
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
||||
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
|
||||
copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
|
||||
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
||||
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
|
||||
cannot_reblog : { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
|
||||
favourite : { id: 'status.favourite', defaultMessage: 'Favourite' },
|
||||
bookmark : { id: 'status.bookmark', defaultMessage: 'Bookmark' },
|
||||
removeBookmark : { id: 'status.remove_bookmark', defaultMessage: 'Remove bookmark' },
|
||||
open : { id: 'status.open', defaultMessage: 'Expand this status' },
|
||||
report : { id: 'status.report', defaultMessage: 'Report @{name}' },
|
||||
muteConversation : { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
||||
unmuteConversation : { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
||||
pin : { id: 'status.pin', defaultMessage: 'Pin on profile' },
|
||||
unpin : { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
|
||||
embed : { id: 'status.embed', defaultMessage: 'Embed' },
|
||||
admin_account : { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
||||
admin_status : { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
|
||||
copy : { id: 'status.copy', defaultMessage: 'Copy link to status' },
|
||||
blockDomain : { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
||||
unblockDomain : { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||
unmute : { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
||||
unblock : { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, { status }) => ({
|
||||
@ -56,28 +56,28 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map.isRequired,
|
||||
relationship: ImmutablePropTypes.map,
|
||||
onReply: PropTypes.func,
|
||||
onFavourite: PropTypes.func,
|
||||
onReblog: PropTypes.func,
|
||||
onDelete: PropTypes.func,
|
||||
onDirect: PropTypes.func,
|
||||
onMention: PropTypes.func,
|
||||
onMute: PropTypes.func,
|
||||
onUnmute: PropTypes.func,
|
||||
onBlock: PropTypes.func,
|
||||
onUnblock: PropTypes.func,
|
||||
onBlockDomain: PropTypes.func,
|
||||
onUnblockDomain: PropTypes.func,
|
||||
onReport: PropTypes.func,
|
||||
onEmbed: PropTypes.func,
|
||||
status : ImmutablePropTypes.map.isRequired,
|
||||
relationship : ImmutablePropTypes.map,
|
||||
onReply : PropTypes.func,
|
||||
onFavourite : PropTypes.func,
|
||||
onReblog : PropTypes.func,
|
||||
onDelete : PropTypes.func,
|
||||
onDirect : PropTypes.func,
|
||||
onMention : PropTypes.func,
|
||||
onMute : PropTypes.func,
|
||||
onUnmute : PropTypes.func,
|
||||
onBlock : PropTypes.func,
|
||||
onUnblock : PropTypes.func,
|
||||
onBlockDomain : PropTypes.func,
|
||||
onUnblockDomain : PropTypes.func,
|
||||
onReport : PropTypes.func,
|
||||
onEmbed : PropTypes.func,
|
||||
onMuteConversation: PropTypes.func,
|
||||
onPin: PropTypes.func,
|
||||
onBookmark: PropTypes.func,
|
||||
withDismiss: PropTypes.bool,
|
||||
scrollKey: PropTypes.string,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onPin : PropTypes.func,
|
||||
onBookmark : PropTypes.func,
|
||||
withDismiss : PropTypes.bool,
|
||||
scrollKey : PropTypes.string,
|
||||
intl : PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
// Avoid checking props that are functions (and whose equality will always
|
||||
@ -86,7 +86,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
'status',
|
||||
'relationship',
|
||||
'withDismiss',
|
||||
]
|
||||
];
|
||||
|
||||
handleReplyClick = () => {
|
||||
if (me) {
|
||||
@ -94,16 +94,16 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
} else {
|
||||
this._openInteractionDialog('reply');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleShareClick = () => {
|
||||
navigator.share({
|
||||
text: this.props.status.get('search_index'),
|
||||
url: this.props.status.get('url'),
|
||||
url : this.props.status.get('url'),
|
||||
}).catch((e) => {
|
||||
if (e.name !== 'AbortError') console.error(e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleFavouriteClick = () => {
|
||||
if (me) {
|
||||
@ -111,7 +111,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
} else {
|
||||
this._openInteractionDialog('favourite');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleReblogClick = e => {
|
||||
if (me) {
|
||||
@ -119,35 +119,35 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
} else {
|
||||
this._openInteractionDialog('reblog');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_openInteractionDialog = type => {
|
||||
window.open(`/interact/${this.props.status.get('id')}?type=${type}`, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
|
||||
}
|
||||
};
|
||||
|
||||
handleBookmarkClick = () => {
|
||||
this.props.onBookmark(this.props.status);
|
||||
}
|
||||
};
|
||||
|
||||
handleDeleteClick = () => {
|
||||
this.props.onDelete(this.props.status, this.context.router.history);
|
||||
}
|
||||
};
|
||||
|
||||
handleRedraftClick = () => {
|
||||
this.props.onDelete(this.props.status, this.context.router.history, true);
|
||||
}
|
||||
};
|
||||
|
||||
handlePinClick = () => {
|
||||
this.props.onPin(this.props.status);
|
||||
}
|
||||
};
|
||||
|
||||
handleMentionClick = () => {
|
||||
this.props.onMention(this.props.status.get('account'), this.context.router.history);
|
||||
}
|
||||
};
|
||||
|
||||
handleDirectClick = () => {
|
||||
this.props.onDirect(this.props.status.get('account'), this.context.router.history);
|
||||
}
|
||||
};
|
||||
|
||||
handleMuteClick = () => {
|
||||
const { status, relationship, onMute, onUnmute } = this.props;
|
||||
@ -158,7 +158,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
} else {
|
||||
onMute(account);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleBlockClick = () => {
|
||||
const { status, relationship, onBlock, onUnblock } = this.props;
|
||||
@ -169,37 +169,37 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
} else {
|
||||
onBlock(status);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleBlockDomain = () => {
|
||||
const { status, onBlockDomain } = this.props;
|
||||
const account = status.get('account');
|
||||
|
||||
onBlockDomain(account.get('acct').split('@')[1]);
|
||||
}
|
||||
};
|
||||
|
||||
handleUnblockDomain = () => {
|
||||
const { status, onUnblockDomain } = this.props;
|
||||
const account = status.get('account');
|
||||
|
||||
onUnblockDomain(account.get('acct').split('@')[1]);
|
||||
}
|
||||
};
|
||||
|
||||
handleOpen = () => {
|
||||
this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
|
||||
}
|
||||
};
|
||||
|
||||
handleEmbed = () => {
|
||||
this.props.onEmbed(this.props.status);
|
||||
}
|
||||
};
|
||||
|
||||
handleReport = () => {
|
||||
this.props.onReport(this.props.status);
|
||||
}
|
||||
};
|
||||
|
||||
handleConversationMuteClick = () => {
|
||||
this.props.onMuteConversation(this.props.status);
|
||||
}
|
||||
};
|
||||
|
||||
handleCopy = () => {
|
||||
const url = this.props.status.get('url');
|
||||
@ -218,9 +218,9 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const { status, relationship, intl, withDismiss, scrollKey } = this.props;
|
||||
|
||||
const mutingConversation = status.get('muted');
|
||||
@ -230,46 +230,85 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
|
||||
let menu = [];
|
||||
|
||||
menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen });
|
||||
menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen , iconName: 'arrow-right' });
|
||||
|
||||
if (publicStatus) {
|
||||
menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
|
||||
menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
|
||||
menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy, iconName: 'copy' });
|
||||
menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed, iconName: 'screen' });
|
||||
}
|
||||
|
||||
menu.push({ text: intl.formatMessage(status.get('bookmarked') ? messages.removeBookmark : messages.bookmark), action: this.handleBookmarkClick });
|
||||
menu.push({
|
||||
text : intl.formatMessage(status.get('bookmarked') ? messages.removeBookmark : messages.bookmark),
|
||||
action: this.handleBookmarkClick,
|
||||
iconName: 'bookmark',
|
||||
});
|
||||
menu.push(null);
|
||||
|
||||
if (status.getIn(['account', 'id']) === me || withDismiss) {
|
||||
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||
menu.push({
|
||||
text : intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation),
|
||||
action: this.handleConversationMuteClick, iconName: 'hide',
|
||||
});
|
||||
menu.push(null);
|
||||
}
|
||||
|
||||
if (status.getIn(['account', 'id']) === me) {
|
||||
if (publicStatus) {
|
||||
menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
|
||||
menu.push({
|
||||
text : intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin),
|
||||
action: this.handlePinClick,
|
||||
iconName: 'gears',
|
||||
});
|
||||
}
|
||||
|
||||
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
|
||||
menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick });
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.handleMentionClick });
|
||||
menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.handleDirectClick });
|
||||
menu.push({
|
||||
text : intl.formatMessage(messages.mention, { name: account.get('username') }),
|
||||
action: this.handleMentionClick,
|
||||
iconName: 'plane',
|
||||
});
|
||||
menu.push({
|
||||
text : intl.formatMessage(messages.direct, { name: account.get('username') }),
|
||||
action: this.handleDirectClick,
|
||||
iconName: 'enveloppe-o',
|
||||
});
|
||||
menu.push(null);
|
||||
|
||||
if (relationship && relationship.get('muting')) {
|
||||
menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.handleMuteClick });
|
||||
menu.push({
|
||||
text : intl.formatMessage(messages.unmute, { name: account.get('username') }),
|
||||
action: this.handleMuteClick,
|
||||
iconName: 'times',
|
||||
});
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.handleMuteClick });
|
||||
menu.push({
|
||||
text : intl.formatMessage(messages.mute, { name: account.get('username') }),
|
||||
action: this.handleMuteClick,
|
||||
iconName: 'times',
|
||||
});
|
||||
}
|
||||
|
||||
if (relationship && relationship.get('blocking')) {
|
||||
menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.handleBlockClick });
|
||||
menu.push({
|
||||
text : intl.formatMessage(messages.unblock, { name: account.get('username') }),
|
||||
action: this.handleBlockClick,
|
||||
iconName: 'plus',
|
||||
});
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.handleBlockClick });
|
||||
menu.push({
|
||||
text : intl.formatMessage(messages.block, { name: account.get('username') }),
|
||||
action: this.handleBlockClick,
|
||||
iconName: 'times',
|
||||
});
|
||||
}
|
||||
|
||||
menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.handleReport });
|
||||
menu.push({
|
||||
text : intl.formatMessage(messages.report, { name: account.get('username') }),
|
||||
action: this.handleReport,
|
||||
iconName: 'flag',
|
||||
});
|
||||
|
||||
if (account.get('acct') !== account.get('username')) {
|
||||
const domain = account.get('acct').split('@')[1];
|
||||
@ -285,8 +324,18 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
|
||||
if (isStaff) {
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
||||
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
||||
menu.push({
|
||||
text: intl.formatMessage(messages.admin_account,
|
||||
{ name: account.get('username') }),
|
||||
href: `/admin/accounts/${status.getIn(['account', 'id'])}`,
|
||||
iconName: 'gears',
|
||||
|
||||
});
|
||||
menu.push({
|
||||
text: intl.formatMessage(messages.admin_status),
|
||||
href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}`,
|
||||
iconName: 'menu',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,14 +363,42 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
const shareButton = ('share' in navigator) && publicStatus && (
|
||||
<IconButton className='status__action-bar-button' title={intl.formatMessage(messages.share)} icon='share-alt' onClick={this.handleShareClick} />
|
||||
<IconButton
|
||||
className='status__action-bar-button'
|
||||
title={intl.formatMessage(messages.share)}
|
||||
icon='share-alt'
|
||||
onClick={this.handleShareClick}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className='status__action-bar'>
|
||||
<IconButton className='status__action-bar-button' title={replyTitle} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} counter={status.get('replies_count')} obfuscateCount />
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} pressed={status.get('reblogged')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} />
|
||||
<IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} pressed={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} />
|
||||
<IconButton
|
||||
className='status__action-bar-button'
|
||||
title={replyTitle}
|
||||
icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon}
|
||||
onClick={this.handleReplyClick}
|
||||
counter={status.get('replies_count')}
|
||||
obfuscateCount
|
||||
/>
|
||||
<IconButton
|
||||
className={classNames('status__action-bar-button', { reblogPrivate })}
|
||||
disabled={!publicStatus && !reblogPrivate}
|
||||
active={status.get('reblogged')}
|
||||
pressed={status.get('reblogged')}
|
||||
title={reblogTitle}
|
||||
icon='retweet'
|
||||
onClick={this.handleReblogClick}
|
||||
/>
|
||||
<IconButton
|
||||
className='status__action-bar-button star-icon'
|
||||
animate
|
||||
active={status.get('favourited')}
|
||||
pressed={status.get('favourited')}
|
||||
title={intl.formatMessage(messages.favourite)}
|
||||
icon='star'
|
||||
onClick={this.handleFavouriteClick}
|
||||
/>
|
||||
|
||||
{shareButton}
|
||||
|
||||
@ -336,8 +413,8 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
direction='right'
|
||||
title={intl.formatMessage(messages.more)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div >
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import { FormattedMessage } from 'react-intl';
|
||||
import Permalink from './permalink';
|
||||
import classnames from 'classnames';
|
||||
import PollContainer from 'mastodon/containers/poll_container';
|
||||
import Icon from 'mastodon/components/icon';
|
||||
import { autoPlayGif } from 'mastodon/initial_state';
|
||||
|
||||
const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
|
||||
@ -31,7 +30,7 @@ export default class StatusContent extends React.PureComponent {
|
||||
hidden: true,
|
||||
};
|
||||
|
||||
_updateStatusLinks () {
|
||||
_updateStatusLinks() {
|
||||
const node = this.node;
|
||||
|
||||
if (!node) {
|
||||
@ -70,13 +69,13 @@ export default class StatusContent extends React.PureComponent {
|
||||
&& node.clientHeight > MAX_HEIGHT
|
||||
&& this.props.status.get('spoiler_text').length === 0;
|
||||
|
||||
if(this.props.onCollapsedToggle) this.props.onCollapsedToggle(collapsed);
|
||||
if (this.props.onCollapsedToggle) this.props.onCollapsedToggle(collapsed);
|
||||
|
||||
this.props.status.set('collapsed', collapsed);
|
||||
}
|
||||
}
|
||||
|
||||
_updateStatusEmojis () {
|
||||
_updateStatusEmojis() {
|
||||
const node = this.node;
|
||||
|
||||
if (!node || autoPlayGif) {
|
||||
@ -97,12 +96,12 @@ export default class StatusContent extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
componentDidMount() {
|
||||
this._updateStatusLinks();
|
||||
this._updateStatusEmojis();
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
componentDidUpdate() {
|
||||
this._updateStatusLinks();
|
||||
this._updateStatusEmojis();
|
||||
}
|
||||
@ -140,8 +139,8 @@ export default class StatusContent extends React.PureComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
const [ startX, startY ] = this.startXY;
|
||||
const [ deltaX, deltaY ] = [Math.abs(e.clientX - startX), Math.abs(e.clientY - startY)];
|
||||
const [startX, startY] = this.startXY;
|
||||
const [deltaX, deltaY] = [Math.abs(e.clientX - startX), Math.abs(e.clientY - startY)];
|
||||
|
||||
let element = e.target;
|
||||
while (element) {
|
||||
@ -173,7 +172,7 @@ export default class StatusContent extends React.PureComponent {
|
||||
this.node = c;
|
||||
};
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const { status } = this.props;
|
||||
|
||||
if (status.get('content').length === 0) {
|
||||
@ -202,10 +201,13 @@ export default class StatusContent extends React.PureComponent {
|
||||
className='status__content__read-more-button'
|
||||
onClick={this.props.onClick}
|
||||
>
|
||||
<i className='fa fa-arrow-right' />
|
||||
<span className='see-more'>
|
||||
<FormattedMessage
|
||||
id='status.show_thread'
|
||||
defaultMessage='Show thread'
|
||||
/> <i className='fa fa-comment' />
|
||||
/>
|
||||
</span >
|
||||
</button >
|
||||
);
|
||||
|
||||
@ -215,10 +217,14 @@ export default class StatusContent extends React.PureComponent {
|
||||
onClick={this.props.onClick}
|
||||
key='read-more'
|
||||
>
|
||||
<i className='fa fa-comment' />
|
||||
<span className='see-more'>
|
||||
|
||||
<FormattedMessage
|
||||
id='status.read_more'
|
||||
defaultMessage='Read more'
|
||||
/> <i className='fa fa-comment' />
|
||||
/>
|
||||
</span >
|
||||
</button >
|
||||
);
|
||||
|
||||
@ -226,19 +232,37 @@ export default class StatusContent extends React.PureComponent {
|
||||
let mentionsPlaceholder = '';
|
||||
|
||||
const mentionLinks = status.get('mentions').map(item => (
|
||||
<Permalink to={`/accounts/${item.get('id')}`} href={item.get('url')} key={item.get('id')} className='mention'>
|
||||
@<span>{item.get('username')}</span>
|
||||
</Permalink>
|
||||
<Permalink
|
||||
to={`/accounts/${item.get('id')}`}
|
||||
href={item.get('url')}
|
||||
key={item.get('id')}
|
||||
className='mention'
|
||||
>
|
||||
@<span >{item.get('username')}</span >
|
||||
</Permalink >
|
||||
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);
|
||||
|
||||
const toggleText = hidden ? <FormattedMessage id='status.show_more' defaultMessage='Show more' /> : <FormattedMessage id='status.show_less' defaultMessage='Show less' />;
|
||||
const toggleText = hidden ? (<FormattedMessage
|
||||
id='status.show_more'
|
||||
defaultMessage='Show more'
|
||||
/>) : (<FormattedMessage
|
||||
id='status.show_less'
|
||||
defaultMessage='Show less'
|
||||
/>);
|
||||
|
||||
if (hidden) {
|
||||
mentionsPlaceholder = <div>{mentionLinks}</div>;
|
||||
mentionsPlaceholder = <div >{mentionLinks}</div >;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames} ref={this.setRef} tabIndex='0' style={directionStyle} onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
|
||||
<div
|
||||
className={classNames}
|
||||
ref={this.setRef}
|
||||
tabIndex='0'
|
||||
style={directionStyle}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onMouseUp={this.handleMouseUp}
|
||||
>
|
||||
<p style={{ marginBottom: hidden && status.get('mentions').isEmpty() ? '0px' : null }}>
|
||||
<span dangerouslySetInnerHTML={spoilerContent} />
|
||||
{' '}
|
||||
|
@ -21,6 +21,10 @@ import { length } from 'stringz';
|
||||
import { countableText } from '../util/counter';
|
||||
import Icon from 'mastodon/components/icon';
|
||||
|
||||
// import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
|
||||
// import { mascot } from '../../initial_state';
|
||||
|
||||
|
||||
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -4,35 +4,34 @@ import NavigationContainer from './containers/navigation_container';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { connect } from 'react-redux';
|
||||
import { mountCompose, unmountCompose } from '../../actions/compose';
|
||||
import { changeComposing, mountCompose, unmountCompose } from '../../actions/compose';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { injectIntl, defineMessages } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import SearchContainer from './containers/search_container';
|
||||
import Motion from '../ui/util/optional_motion';
|
||||
import spring from 'react-motion/lib/spring';
|
||||
import SearchResultsContainer from './containers/search_results_container';
|
||||
import { changeComposing } from '../../actions/compose';
|
||||
import { openModal } from 'mastodon/actions/modal';
|
||||
import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
|
||||
import cipherblissLogo from '../../../images/logo_cipherbliss.png';
|
||||
import { mascot } from '../../initial_state';
|
||||
import Icon from 'mastodon/components/icon';
|
||||
import { logOut } from 'mastodon/utils/log_out';
|
||||
|
||||
const messages = defineMessages({
|
||||
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||
start : { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||
home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' },
|
||||
notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' },
|
||||
public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
|
||||
community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||
compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' },
|
||||
public : { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
|
||||
community : { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
|
||||
preferences : { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||
logout : { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
|
||||
compose : { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' },
|
||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
columns: state.getIn(['settings', 'columns']),
|
||||
columns : state.getIn(['settings', 'columns']),
|
||||
showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : ownProps.isSearchPage,
|
||||
});
|
||||
|
||||
@ -41,15 +40,15 @@ export default @connect(mapStateToProps)
|
||||
class Compose extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
columns: ImmutablePropTypes.list.isRequired,
|
||||
multiColumn: PropTypes.bool,
|
||||
showSearch: PropTypes.bool,
|
||||
dispatch : PropTypes.func.isRequired,
|
||||
columns : ImmutablePropTypes.list.isRequired,
|
||||
multiColumn : PropTypes.bool,
|
||||
showSearch : PropTypes.bool,
|
||||
isSearchPage: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
intl : PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
componentDidMount() {
|
||||
const { isSearchPage } = this.props;
|
||||
|
||||
if (!isSearchPage) {
|
||||
@ -57,7 +56,7 @@ class Compose extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
componentWillUnmount() {
|
||||
const { isSearchPage } = this.props;
|
||||
|
||||
if (!isSearchPage) {
|
||||
@ -72,23 +71,23 @@ class Compose extends React.PureComponent {
|
||||
e.stopPropagation();
|
||||
|
||||
dispatch(openModal('CONFIRM', {
|
||||
message: intl.formatMessage(messages.logoutMessage),
|
||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
||||
message : intl.formatMessage(messages.logoutMessage),
|
||||
confirm : intl.formatMessage(messages.logoutConfirm),
|
||||
onConfirm: () => logOut(),
|
||||
}));
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
onFocus = () => {
|
||||
this.props.dispatch(changeComposing(true));
|
||||
}
|
||||
};
|
||||
|
||||
onBlur = () => {
|
||||
this.props.dispatch(changeComposing(false));
|
||||
}
|
||||
};
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const { multiColumn, showSearch, isSearchPage, intl } = this.props;
|
||||
|
||||
let header = '';
|
||||
@ -97,51 +96,126 @@ class Compose extends React.PureComponent {
|
||||
const { columns } = this.props;
|
||||
header = (
|
||||
<nav className='drawer__header'>
|
||||
<Link to='/getting-started' className='drawer__tab' title={intl.formatMessage(messages.start)} aria-label={intl.formatMessage(messages.start)}><Icon id='bars' fixedWidth /></Link>
|
||||
<Link
|
||||
to='/getting-started'
|
||||
className='drawer__tab'
|
||||
title={intl.formatMessage(messages.start)}
|
||||
aria-label={intl.formatMessage(messages.start)}
|
||||
><Icon
|
||||
id='bars'
|
||||
fixedWidth
|
||||
/></Link >
|
||||
{!columns.some(column => column.get('id') === 'HOME') && (
|
||||
<Link to='/timelines/home' className='drawer__tab' title={intl.formatMessage(messages.home_timeline)} aria-label={intl.formatMessage(messages.home_timeline)}><Icon id='home' fixedWidth /></Link>
|
||||
<Link
|
||||
to='/timelines/home'
|
||||
className='drawer__tab'
|
||||
title={intl.formatMessage(messages.home_timeline)}
|
||||
aria-label={intl.formatMessage(messages.home_timeline)}
|
||||
><Icon
|
||||
id='home'
|
||||
fixedWidth
|
||||
/></Link >
|
||||
)}
|
||||
{!columns.some(column => column.get('id') === 'NOTIFICATIONS') && (
|
||||
<Link to='/notifications' className='drawer__tab' title={intl.formatMessage(messages.notifications)} aria-label={intl.formatMessage(messages.notifications)}><Icon id='bell' fixedWidth /></Link>
|
||||
<Link
|
||||
to='/notifications'
|
||||
className='drawer__tab'
|
||||
title={intl.formatMessage(messages.notifications)}
|
||||
aria-label={intl.formatMessage(messages.notifications)}
|
||||
><Icon
|
||||
id='bell'
|
||||
fixedWidth
|
||||
/></Link >
|
||||
)}
|
||||
{!columns.some(column => column.get('id') === 'COMMUNITY') && (
|
||||
<Link to='/timelines/public/local' className='drawer__tab' title={intl.formatMessage(messages.community)} aria-label={intl.formatMessage(messages.community)}><Icon id='users' fixedWidth /></Link>
|
||||
<Link
|
||||
to='/timelines/public/local'
|
||||
className='drawer__tab'
|
||||
title={intl.formatMessage(messages.community)}
|
||||
aria-label={intl.formatMessage(messages.community)}
|
||||
><Icon
|
||||
id='users'
|
||||
fixedWidth
|
||||
/></Link >
|
||||
)}
|
||||
{!columns.some(column => column.get('id') === 'PUBLIC') && (
|
||||
<Link to='/timelines/public' className='drawer__tab' title={intl.formatMessage(messages.public)} aria-label={intl.formatMessage(messages.public)}><Icon id='globe' fixedWidth /></Link>
|
||||
<Link
|
||||
to='/timelines/public'
|
||||
className='drawer__tab'
|
||||
title={intl.formatMessage(messages.public)}
|
||||
aria-label={intl.formatMessage(messages.public)}
|
||||
><Icon
|
||||
id='globe'
|
||||
fixedWidth
|
||||
/></Link >
|
||||
)}
|
||||
<a href='/settings/preferences' className='drawer__tab' title={intl.formatMessage(messages.preferences)} aria-label={intl.formatMessage(messages.preferences)}><Icon id='cog' fixedWidth /></a>
|
||||
<a href='/auth/sign_out' className='drawer__tab' title={intl.formatMessage(messages.logout)} aria-label={intl.formatMessage(messages.logout)} onClick={this.handleLogoutClick}><Icon id='sign-out' fixedWidth /></a>
|
||||
</nav>
|
||||
<a
|
||||
href='/settings/preferences'
|
||||
className='drawer__tab'
|
||||
title={intl.formatMessage(messages.preferences)}
|
||||
aria-label={intl.formatMessage(messages.preferences)}
|
||||
><Icon
|
||||
id='cog'
|
||||
fixedWidth
|
||||
/></a >
|
||||
<a
|
||||
href='/auth/sign_out'
|
||||
className='drawer__tab'
|
||||
title={intl.formatMessage(messages.logout)}
|
||||
aria-label={intl.formatMessage(messages.logout)}
|
||||
onClick={this.handleLogoutClick}
|
||||
><Icon
|
||||
id='sign-out'
|
||||
fixedWidth
|
||||
/></a >
|
||||
</nav >
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='drawer' role='region' aria-label={intl.formatMessage(messages.compose)}>
|
||||
<div
|
||||
className='drawer'
|
||||
role='region'
|
||||
aria-label={intl.formatMessage(messages.compose)}
|
||||
>
|
||||
{header}
|
||||
|
||||
{(multiColumn || isSearchPage) && <SearchContainer /> }
|
||||
{(multiColumn || isSearchPage) && <SearchContainer />}
|
||||
|
||||
<div className='drawer__pager'>
|
||||
{!isSearchPage && <div className='drawer__inner' onFocus={this.onFocus}>
|
||||
{!isSearchPage && <div
|
||||
className='drawer__inner'
|
||||
onFocus={this.onFocus}
|
||||
>
|
||||
<NavigationContainer onClose={this.onBlur} />
|
||||
|
||||
<ComposeFormContainer />
|
||||
|
||||
<div className='drawer__inner__mastodon'>
|
||||
<img alt='' draggable='false' src={mascot || elephantUIPlane} />
|
||||
</div>
|
||||
</div>}
|
||||
<img
|
||||
className='cipherbliss_logo'
|
||||
src={mascot || cipherblissLogo}
|
||||
alt='logo'
|
||||
/>
|
||||
{/*<img alt='' draggable='false' src={mascot || elephantUIPlane} />*/}
|
||||
</div >
|
||||
</div >}
|
||||
|
||||
<Motion defaultStyle={{ x: isSearchPage ? 0 : -100 }} style={{ x: spring(showSearch || isSearchPage ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
|
||||
<Motion
|
||||
defaultStyle={{ x: isSearchPage ? 0 : -100 }}
|
||||
style={{ x: spring(showSearch || isSearchPage ? 0 : -100, { stiffness: 210, damping: 20 }) }}
|
||||
>
|
||||
{({ x }) => (
|
||||
<div className='drawer__inner darker' style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}>
|
||||
<div
|
||||
className='drawer__inner darker'
|
||||
style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}
|
||||
>
|
||||
<SearchResultsContainer />
|
||||
</div>
|
||||
</div >
|
||||
)}
|
||||
</Motion>
|
||||
</div>
|
||||
</div>
|
||||
</Motion >
|
||||
</div >
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@ class AccountAuthorize extends ImmutablePureComponent {
|
||||
const { intl, account, onAuthorize, onReject } = this.props;
|
||||
const content = { __html: account.get('note_emojified') };
|
||||
|
||||
|
||||
const fields = account.get('fields');
|
||||
return (
|
||||
<div className='account-authorize__wrapper'>
|
||||
@ -46,7 +45,7 @@ class AccountAuthorize extends ImmutablePureComponent {
|
||||
</Permalink >
|
||||
<div className='more'>
|
||||
{account.get('remote_url')}
|
||||
</div>
|
||||
</div >
|
||||
|
||||
<div
|
||||
className='account__header__content'
|
||||
@ -85,7 +84,8 @@ class AccountAuthorize extends ImmutablePureComponent {
|
||||
to={`/accounts/${account.get('id')}/followers`}
|
||||
title={intl.formatNumber(account.get('followers_count'))}
|
||||
>
|
||||
<strong >{(account.get('followers_count'))}</strong > <FormattedMessage
|
||||
<strong >{(account.get('followers_count'))}</strong >
|
||||
<FormattedMessage
|
||||
id='account.followers'
|
||||
defaultMessage='Followers'
|
||||
/>
|
||||
@ -94,13 +94,18 @@ class AccountAuthorize extends ImmutablePureComponent {
|
||||
</span >
|
||||
|
||||
<div className='account--panel'>
|
||||
<div className='account--panel__button'><IconButton
|
||||
<div className='account--panel__button text-center'>
|
||||
<IconButton
|
||||
title={intl.formatMessage(messages.authorize)}
|
||||
size='50'
|
||||
icon='check'
|
||||
onClick={onAuthorize}
|
||||
/></div >
|
||||
<div className='account--panel__button'><IconButton
|
||||
/>
|
||||
</div >
|
||||
<div className='account--panel__button text-center'>
|
||||
<IconButton
|
||||
title={intl.formatMessage(messages.reject)}
|
||||
size='50'
|
||||
icon='times'
|
||||
onClick={onReject}
|
||||
/></div >
|
||||
|
@ -1,3 +1,8 @@
|
||||
.columns-area__panels {
|
||||
|
||||
background: url('../images/elephant_ui_plane.svg') no-repeat left bottom fixed, url('../images/logo_cipherbliss.png') no-repeat right bottom fixed;
|
||||
}
|
||||
|
||||
.status__content {
|
||||
min-height: 5em;
|
||||
}
|
||||
@ -21,11 +26,12 @@
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.fa{
|
||||
&:hover{
|
||||
.fa {
|
||||
&:hover {
|
||||
color: $gold-star;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
padding: .5em;
|
||||
@ -38,7 +44,8 @@
|
||||
&:visited {
|
||||
color: #528dc8;
|
||||
}
|
||||
&:hover{
|
||||
|
||||
&:hover {
|
||||
color: $gold-star;
|
||||
}
|
||||
|
||||
@ -61,10 +68,14 @@
|
||||
|
||||
.compose-form {
|
||||
.reply-indicator {
|
||||
display: none;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.autosuggest-textarea__textarea{
|
||||
color: #528dc8;
|
||||
}
|
||||
|
||||
.account-authorize--more-data {
|
||||
padding: 1em;
|
||||
color: white;
|
||||
@ -77,18 +88,51 @@
|
||||
}
|
||||
}
|
||||
|
||||
.account__relationship{
|
||||
button{
|
||||
.account__relationship {
|
||||
button {
|
||||
width: 10em;
|
||||
height: 3em;
|
||||
}
|
||||
}
|
||||
|
||||
.account--panel {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.account--panel__button {
|
||||
padding: 1em;
|
||||
|
||||
button {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.status__content__read-more-button {
|
||||
.fa{
|
||||
float:left;
|
||||
}
|
||||
.see-more {
|
||||
opacity: 0;
|
||||
transition: opacity ease 0.2s;
|
||||
float:left;
|
||||
margin-left: 1em;
|
||||
}
|
||||
&:hover .see-more{
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu__item{
|
||||
.fa{
|
||||
margin-right:1em;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 600px) {
|
||||
.columns-area__panels {
|
||||
|
||||
background: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user