Revert post timestamps to link to canonical url (#1249)
After much discussion (#1214), I have decided that the solution we are going with for timestamp-clicking is: - clicking a post timestamp from most views takes you to the "focus" view for that post, identical to v3 behavior - clicking the timestamp from the "focus" view opens the link to the canonical post on the server of origin, identical to v3 behavior This is an application of this patch from the queer.party folks: https://commit.pup.cloud/maff/queer.party/src/branch/master/patches/4.0.0_4-revert-captive-links.patch Fixes #1214
This commit is contained in:
parent
be7c7c717a
commit
b8802af45c
|
@ -3,13 +3,13 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Avatar from './avatar';
|
import Avatar from './avatar';
|
||||||
import DisplayName from './display_name';
|
import DisplayName from './display_name';
|
||||||
|
import Permalink from './permalink';
|
||||||
import IconButton from './icon_button';
|
import IconButton from './icon_button';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { me } from '../initial_state';
|
import { me } from '../initial_state';
|
||||||
import RelativeTimestamp from './relative_timestamp';
|
import RelativeTimestamp from './relative_timestamp';
|
||||||
import Skeleton from 'mastodon/components/skeleton';
|
import Skeleton from 'mastodon/components/skeleton';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
||||||
|
@ -140,11 +140,11 @@ class Account extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='account'>
|
<div className='account'>
|
||||||
<div className='account__wrapper'>
|
<div className='account__wrapper'>
|
||||||
<Link key={account.get('id')} className='account__display-name' title={account.get('acct')} to={`/@${account.get('acct')}`}>
|
<Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}>
|
||||||
<div className='account__avatar-wrapper'><Avatar account={account} size={size} /></div>
|
<div className='account__avatar-wrapper'><Avatar account={account} size={size} /></div>
|
||||||
{mute_expires_at}
|
{mute_expires_at}
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
<div className='account__relationship'>
|
<div className='account__relationship'>
|
||||||
{buttons}
|
{buttons}
|
||||||
|
|
|
@ -50,7 +50,7 @@ export default class Trends extends React.PureComponent {
|
||||||
<Hashtag
|
<Hashtag
|
||||||
key={hashtag.name}
|
key={hashtag.name}
|
||||||
name={hashtag.name}
|
name={hashtag.name}
|
||||||
to={`/admin/tags/${hashtag.id}`}
|
href={`/admin/tags/${hashtag.id}`}
|
||||||
people={hashtag.history[0].accounts * 1 + hashtag.history[1].accounts * 1}
|
people={hashtag.history[0].accounts * 1 + hashtag.history[1].accounts * 1}
|
||||||
uses={hashtag.history[0].uses * 1 + hashtag.history[1].uses * 1}
|
uses={hashtag.history[0].uses * 1 + hashtag.history[1].uses * 1}
|
||||||
history={hashtag.history.reverse().map(day => day.uses)}
|
history={hashtag.history.reverse().map(day => day.uses)}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Sparklines, SparklinesCurve } from 'react-sparklines';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from './permalink';
|
||||||
import ShortNumber from 'mastodon/components/short_number';
|
import ShortNumber from 'mastodon/components/short_number';
|
||||||
import Skeleton from 'mastodon/components/skeleton';
|
import Skeleton from 'mastodon/components/skeleton';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
@ -53,6 +53,7 @@ export const accountsCountRenderer = (displayNumber, pluralReady) => (
|
||||||
export const ImmutableHashtag = ({ hashtag }) => (
|
export const ImmutableHashtag = ({ hashtag }) => (
|
||||||
<Hashtag
|
<Hashtag
|
||||||
name={hashtag.get('name')}
|
name={hashtag.get('name')}
|
||||||
|
href={hashtag.get('url')}
|
||||||
to={`/tags/${hashtag.get('name')}`}
|
to={`/tags/${hashtag.get('name')}`}
|
||||||
people={hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1}
|
people={hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1}
|
||||||
history={hashtag.get('history').reverse().map((day) => day.get('uses')).toArray()}
|
history={hashtag.get('history').reverse().map((day) => day.get('uses')).toArray()}
|
||||||
|
@ -63,12 +64,12 @@ ImmutableHashtag.propTypes = {
|
||||||
hashtag: ImmutablePropTypes.map.isRequired,
|
hashtag: ImmutablePropTypes.map.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Hashtag = ({ name, to, people, uses, history, className, description, withGraph }) => (
|
const Hashtag = ({ name, href, to, people, uses, history, className, description, withGraph }) => (
|
||||||
<div className={classNames('trends__item', className)}>
|
<div className={classNames('trends__item', className)}>
|
||||||
<div className='trends__item__name'>
|
<div className='trends__item__name'>
|
||||||
<Link to={to}>
|
<Permalink href={href} to={to}>
|
||||||
{name ? <React.Fragment>#<span>{name}</span></React.Fragment> : <Skeleton width={50} />}
|
{name ? <React.Fragment>#<span>{name}</span></React.Fragment> : <Skeleton width={50} />}
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
{description ? (
|
{description ? (
|
||||||
<span>{description}</span>
|
<span>{description}</span>
|
||||||
|
@ -97,6 +98,7 @@ const Hashtag = ({ name, to, people, uses, history, className, description, with
|
||||||
|
|
||||||
Hashtag.propTypes = {
|
Hashtag.propTypes = {
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
|
href: PropTypes.string,
|
||||||
to: PropTypes.string,
|
to: PropTypes.string,
|
||||||
people: PropTypes.number,
|
people: PropTypes.number,
|
||||||
description: PropTypes.node,
|
description: PropTypes.node,
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
export default class Permalink extends React.PureComponent {
|
||||||
|
|
||||||
|
static contextTypes = {
|
||||||
|
router: PropTypes.object,
|
||||||
|
};
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
href: PropTypes.string.isRequired,
|
||||||
|
to: PropTypes.string.isRequired,
|
||||||
|
children: PropTypes.node,
|
||||||
|
onInterceptClick: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
handleClick = e => {
|
||||||
|
if (this.props.onInterceptClick && this.props.onInterceptClick()) {
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.context.router.history.push(this.props.to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { href, children, className, onInterceptClick, ...other } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a target='_blank' href={href} onClick={this.handleClick} {...other} className={`permalink${className ? ' ' + className : ''}`}>
|
||||||
|
{children}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -378,7 +378,7 @@ class Status extends ImmutablePureComponent {
|
||||||
prepend = (
|
prepend = (
|
||||||
<div className='status__prepend'>
|
<div className='status__prepend'>
|
||||||
<div className='status__prepend-icon-wrapper'><Icon id='retweet' className='status__prepend-icon' fixedWidth /></div>
|
<div className='status__prepend-icon-wrapper'><Icon id='retweet' className='status__prepend-icon' fixedWidth /></div>
|
||||||
<FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} />
|
<FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ class Status extends ImmutablePureComponent {
|
||||||
prepend = (
|
prepend = (
|
||||||
<div className='status__prepend'>
|
<div className='status__prepend'>
|
||||||
<div className='status__prepend-icon-wrapper'><Icon id='reply' className='status__prepend-icon' fixedWidth /></div>
|
<div className='status__prepend-icon-wrapper'><Icon id='reply' className='status__prepend-icon' fixedWidth /></div>
|
||||||
<FormattedMessage id='status.replied_to' defaultMessage='Replied to {name}' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} />
|
<FormattedMessage id='status.replied_to' defaultMessage='Replied to {name}' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -511,12 +511,12 @@ class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
<div className={classNames('status', `status-${status.get('visibility')}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted })} data-id={status.get('id')}>
|
<div className={classNames('status', `status-${status.get('visibility')}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted })} data-id={status.get('id')}>
|
||||||
<div className='status__info'>
|
<div className='status__info'>
|
||||||
<a onClick={this.handleClick} href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
<a onClick={this.handleClick} href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||||
<span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span>
|
<span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span>
|
||||||
<RelativeTimestamp timestamp={status.get('created_at')} />{status.get('edited_at') && <abbr title={intl.formatMessage(messages.edited, { date: intl.formatDate(status.get('edited_at'), { hour12: false, year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) })}> *</abbr>}
|
<RelativeTimestamp timestamp={status.get('created_at')} />{status.get('edited_at') && <abbr title={intl.formatMessage(messages.edited, { date: intl.formatDate(status.get('edited_at'), { hour12: false, year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) })}> *</abbr>}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a onClick={this.handleAccountClick} href={`/@${status.getIn(['account', 'acct'])}`} title={status.getIn(['account', 'acct'])} className='status__display-name' target='_blank' rel='noopener noreferrer'>
|
<a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} title={status.getIn(['account', 'acct'])} className='status__display-name' target='_blank' rel='noopener noreferrer'>
|
||||||
<div className='status__avatar'>
|
<div className='status__avatar'>
|
||||||
{statusAvatar}
|
{statusAvatar}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from './permalink';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import PollContainer from 'mastodon/containers/poll_container';
|
import PollContainer from 'mastodon/containers/poll_container';
|
||||||
import Icon from 'mastodon/components/icon';
|
import Icon from 'mastodon/components/icon';
|
||||||
|
@ -96,10 +96,8 @@ class StatusContent extends React.PureComponent {
|
||||||
if (mention) {
|
if (mention) {
|
||||||
link.addEventListener('click', this.onMentionClick.bind(this, mention), false);
|
link.addEventListener('click', this.onMentionClick.bind(this, mention), false);
|
||||||
link.setAttribute('title', mention.get('acct'));
|
link.setAttribute('title', mention.get('acct'));
|
||||||
link.setAttribute('href', `/@${mention.get('acct')}`);
|
|
||||||
} else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
|
} else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
|
||||||
link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false);
|
link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false);
|
||||||
link.setAttribute('href', `/tags/${link.text.slice(1)}`);
|
|
||||||
} else {
|
} else {
|
||||||
link.setAttribute('title', link.href);
|
link.setAttribute('title', link.href);
|
||||||
link.classList.add('unhandled-link');
|
link.classList.add('unhandled-link');
|
||||||
|
@ -255,9 +253,9 @@ class StatusContent extends React.PureComponent {
|
||||||
let mentionsPlaceholder = '';
|
let mentionsPlaceholder = '';
|
||||||
|
|
||||||
const mentionLinks = status.get('mentions').map(item => (
|
const mentionLinks = status.get('mentions').map(item => (
|
||||||
<Link to={`/@${item.get('acct')}`} key={item.get('id')} className='status-link mention'>
|
<Permalink to={`/@${item.get('acct')}`} href={item.get('url')} key={item.get('id')} className='status-link mention'>
|
||||||
@<span>{item.get('username')}</span>
|
@<span>{item.get('username')}</span>
|
||||||
</Link>
|
</Permalink>
|
||||||
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);
|
)).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' />;
|
||||||
|
|
|
@ -39,6 +39,7 @@ class FeaturedTags extends ImmutablePureComponent {
|
||||||
<Hashtag
|
<Hashtag
|
||||||
key={featuredTag.get('name')}
|
key={featuredTag.get('name')}
|
||||||
name={featuredTag.get('name')}
|
name={featuredTag.get('name')}
|
||||||
|
href={featuredTag.get('url')}
|
||||||
to={`/@${account.get('acct')}/tagged/${featuredTag.get('name')}`}
|
to={`/@${account.get('acct')}/tagged/${featuredTag.get('name')}`}
|
||||||
uses={featuredTag.get('statuses_count') * 1}
|
uses={featuredTag.get('statuses_count') * 1}
|
||||||
withGraph={false}
|
withGraph={false}
|
||||||
|
|
|
@ -129,7 +129,7 @@ export default class MediaItem extends ImmutablePureComponent {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='account-gallery__item' style={{ width, height }}>
|
<div className='account-gallery__item' style={{ width, height }}>
|
||||||
<a className='media-gallery__item-thumbnail' href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'>
|
<a className='media-gallery__item-thumbnail' href={status.get('id')} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'>
|
||||||
<Blurhash
|
<Blurhash
|
||||||
hash={attachment.get('blurhash')}
|
hash={attachment.get('blurhash')}
|
||||||
className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })}
|
className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import AvatarOverlay from '../../../components/avatar_overlay';
|
import AvatarOverlay from '../../../components/avatar_overlay';
|
||||||
import DisplayName from '../../../components/display_name';
|
import DisplayName from '../../../components/display_name';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from 'mastodon/components/permalink';
|
||||||
|
|
||||||
export default class MovedNote extends ImmutablePureComponent {
|
export default class MovedNote extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
@ -23,12 +23,12 @@ export default class MovedNote extends ImmutablePureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='moved-account-banner__action'>
|
<div className='moved-account-banner__action'>
|
||||||
<Link to={`/@${to.get('acct')}`} className='detailed-status__display-name'>
|
<Permalink href={to.get('url')} to={`/@${to.get('acct')}`} className='detailed-status__display-name'>
|
||||||
<div className='detailed-status__display-avatar'><AvatarOverlay account={to} friend={from} /></div>
|
<div className='detailed-status__display-avatar'><AvatarOverlay account={to} friend={from} /></div>
|
||||||
<DisplayName account={to} />
|
<DisplayName account={to} />
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
<Link to={`/@${to.get('acct')}`} className='button'><FormattedMessage id='account.go_to_profile' defaultMessage='Go to profile' /></Link>
|
<Permalink href={to.get('url')} to={`/@${to.get('acct')}`} className='button'><FormattedMessage id='account.go_to_profile' defaultMessage='Go to profile' /></Permalink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ActionBar from './action_bar';
|
import ActionBar from './action_bar';
|
||||||
import Avatar from '../../../components/avatar';
|
import Avatar from '../../../components/avatar';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from '../../../components/permalink';
|
||||||
import IconButton from '../../../components/icon_button';
|
import IconButton from '../../../components/icon_button';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
|
@ -19,15 +19,15 @@ export default class NavigationBar extends ImmutablePureComponent {
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className='navigation-bar'>
|
<div className='navigation-bar'>
|
||||||
<Link to={`/@${this.props.account.get('acct')}`}>
|
<Permalink href={this.props.account.get('url')} to={`/@${this.props.account.get('acct')}`}>
|
||||||
<span style={{ display: 'none' }}>{this.props.account.get('acct')}</span>
|
<span style={{ display: 'none' }}>{this.props.account.get('acct')}</span>
|
||||||
<Avatar account={this.props.account} size={46} />
|
<Avatar account={this.props.account} size={46} />
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
<div className='navigation-bar__profile'>
|
<div className='navigation-bar__profile'>
|
||||||
<Link to={`/@${this.props.account.get('acct')}`}>
|
<Permalink href={this.props.account.get('url')} to={`/@${this.props.account.get('acct')}`}>
|
||||||
<strong className='navigation-bar__profile-account'>@{this.props.account.get('acct')}</strong>
|
<strong className='navigation-bar__profile-account'>@{this.props.account.get('acct')}</strong>
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
<a href='/settings/profile' className='navigation-bar__profile-edit'><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a>
|
<a href='/settings/profile' className='navigation-bar__profile-edit'><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -50,7 +50,7 @@ class ReplyIndicator extends ImmutablePureComponent {
|
||||||
<div className='reply-indicator__header'>
|
<div className='reply-indicator__header'>
|
||||||
<div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} inverted /></div>
|
<div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} inverted /></div>
|
||||||
|
|
||||||
<a href={`/@${status.getIn(['account', 'acct'])}`} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
|
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
|
||||||
<div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
|
<div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
|
||||||
<DisplayName account={status.get('account')} />
|
<DisplayName account={status.get('account')} />
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import AttachmentList from 'mastodon/components/attachment_list';
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
|
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
|
||||||
import AvatarComposite from 'mastodon/components/avatar_composite';
|
import AvatarComposite from 'mastodon/components/avatar_composite';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from 'mastodon/components/permalink';
|
||||||
import IconButton from 'mastodon/components/icon_button';
|
import IconButton from 'mastodon/components/icon_button';
|
||||||
import RelativeTimestamp from 'mastodon/components/relative_timestamp';
|
import RelativeTimestamp from 'mastodon/components/relative_timestamp';
|
||||||
import { HotKeys } from 'react-hotkeys';
|
import { HotKeys } from 'react-hotkeys';
|
||||||
|
@ -133,7 +133,7 @@ class Conversation extends ImmutablePureComponent {
|
||||||
|
|
||||||
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDelete });
|
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDelete });
|
||||||
|
|
||||||
const names = accounts.map(a => <Link to={`/@${a.get('acct')}`} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Link>).reduce((prev, cur) => [prev, ', ', cur]);
|
const names = accounts.map(a => <Permalink to={`/@${a.get('acct')}`} href={a.get('url')} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Permalink>).reduce((prev, cur) => [prev, ', ', cur]);
|
||||||
|
|
||||||
const handlers = {
|
const handlers = {
|
||||||
reply: this.handleReply,
|
reply: this.handleReply,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { connect } from 'react-redux';
|
||||||
import { makeGetAccount } from 'mastodon/selectors';
|
import { makeGetAccount } from 'mastodon/selectors';
|
||||||
import Avatar from 'mastodon/components/avatar';
|
import Avatar from 'mastodon/components/avatar';
|
||||||
import DisplayName from 'mastodon/components/display_name';
|
import DisplayName from 'mastodon/components/display_name';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from 'mastodon/components/permalink';
|
||||||
import Button from 'mastodon/components/button';
|
import Button from 'mastodon/components/button';
|
||||||
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
|
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
|
||||||
import { autoPlayGif, me, unfollowModal } from 'mastodon/initial_state';
|
import { autoPlayGif, me, unfollowModal } from 'mastodon/initial_state';
|
||||||
|
@ -169,7 +169,7 @@ class AccountCard extends ImmutablePureComponent {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='account-card'>
|
<div className='account-card'>
|
||||||
<Link to={`/@${account.get('acct')}`} className='account-card__permalink'>
|
<Permalink href={account.get('url')} to={`/@${account.get('acct')}`} className='account-card__permalink'>
|
||||||
<div className='account-card__header'>
|
<div className='account-card__header'>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
|
@ -183,7 +183,7 @@ class AccountCard extends ImmutablePureComponent {
|
||||||
<div className='account-card__title__avatar'><Avatar account={account} size={56} /></div>
|
<div className='account-card__title__avatar'><Avatar account={account} size={56} /></div>
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
{account.get('note').length > 0 && (
|
{account.get('note').length > 0 && (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { connect } from 'react-redux';
|
||||||
import { makeGetAccount } from 'mastodon/selectors';
|
import { makeGetAccount } from 'mastodon/selectors';
|
||||||
import Avatar from 'mastodon/components/avatar';
|
import Avatar from 'mastodon/components/avatar';
|
||||||
import DisplayName from 'mastodon/components/display_name';
|
import DisplayName from 'mastodon/components/display_name';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from 'mastodon/components/permalink';
|
||||||
import IconButton from 'mastodon/components/icon_button';
|
import IconButton from 'mastodon/components/icon_button';
|
||||||
import { injectIntl, defineMessages } from 'react-intl';
|
import { injectIntl, defineMessages } from 'react-intl';
|
||||||
import { followAccount, unfollowAccount } from 'mastodon/actions/accounts';
|
import { followAccount, unfollowAccount } from 'mastodon/actions/accounts';
|
||||||
|
@ -66,13 +66,13 @@ class Account extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='account follow-recommendations-account'>
|
<div className='account follow-recommendations-account'>
|
||||||
<div className='account__wrapper'>
|
<div className='account__wrapper'>
|
||||||
<Link className='account__display-name account__display-name--with-note' title={account.get('acct')} to={`/@${account.get('acct')}`}>
|
<Permalink className='account__display-name account__display-name--with-note' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}>
|
||||||
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
|
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
|
||||||
|
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
|
|
||||||
<div className='account__note'>{getFirstSentence(account.get('note_plain'))}</div>
|
<div className='account__note'>{getFirstSentence(account.get('note_plain'))}</div>
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
<div className='account__relationship'>
|
<div className='account__relationship'>
|
||||||
{button}
|
{button}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from '../../../components/permalink';
|
||||||
import Avatar from '../../../components/avatar';
|
import Avatar from '../../../components/avatar';
|
||||||
import DisplayName from '../../../components/display_name';
|
import DisplayName from '../../../components/display_name';
|
||||||
import IconButton from '../../../components/icon_button';
|
import IconButton from '../../../components/icon_button';
|
||||||
|
@ -30,10 +30,10 @@ class AccountAuthorize extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='account-authorize__wrapper'>
|
<div className='account-authorize__wrapper'>
|
||||||
<div className='account-authorize'>
|
<div className='account-authorize'>
|
||||||
<Link to={`/@${account.get('acct')}`} className='detailed-status__display-name'>
|
<Permalink href={account.get('url')} to={`/@${account.get('acct')}`} className='detailed-status__display-name'>
|
||||||
<div className='account-authorize__avatar'><Avatar account={account} size={48} /></div>
|
<div className='account-authorize__avatar'><Avatar account={account} size={48} /></div>
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
<div className='account__header__content translate' dangerouslySetInnerHTML={content} />
|
<div className='account__header__content translate' dangerouslySetInnerHTML={content} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Avatar from 'mastodon/components/avatar';
|
import Avatar from 'mastodon/components/avatar';
|
||||||
import DisplayName from 'mastodon/components/display_name';
|
import DisplayName from 'mastodon/components/display_name';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from 'mastodon/components/permalink';
|
||||||
import IconButton from 'mastodon/components/icon_button';
|
import IconButton from 'mastodon/components/icon_button';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
|
@ -42,10 +42,10 @@ class FollowRequest extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='account'>
|
<div className='account'>
|
||||||
<div className='account__wrapper'>
|
<div className='account__wrapper'>
|
||||||
<Link key={account.get('id')} className='account__display-name' title={account.get('acct')} to={`/@${account.get('acct')}`}>
|
<Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}>
|
||||||
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
|
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</Link>
|
</Permalink>
|
||||||
|
|
||||||
<div className='account__relationship'>
|
<div className='account__relationship'>
|
||||||
<IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} />
|
<IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} />
|
||||||
|
|
|
@ -10,7 +10,7 @@ import AccountContainer from 'mastodon/containers/account_container';
|
||||||
import Report from './report';
|
import Report from './report';
|
||||||
import FollowRequestContainer from '../containers/follow_request_container';
|
import FollowRequestContainer from '../containers/follow_request_container';
|
||||||
import Icon from 'mastodon/components/icon';
|
import Icon from 'mastodon/components/icon';
|
||||||
import { Link } from 'react-router-dom';
|
import Permalink from 'mastodon/components/permalink';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -378,7 +378,7 @@ class Notification extends ImmutablePureComponent {
|
||||||
|
|
||||||
const targetAccount = report.get('target_account');
|
const targetAccount = report.get('target_account');
|
||||||
const targetDisplayNameHtml = { __html: targetAccount.get('display_name_html') };
|
const targetDisplayNameHtml = { __html: targetAccount.get('display_name_html') };
|
||||||
const targetLink = <bdi><Link className='notification__display-name' title={targetAccount.get('acct')} to={`/@${targetAccount.get('acct')}`} dangerouslySetInnerHTML={targetDisplayNameHtml} /></bdi>;
|
const targetLink = <bdi><Permalink className='notification__display-name' title={targetAccount.get('acct')} href={targetAccount.get('url')} to={`/@${targetAccount.get('acct')}`} dangerouslySetInnerHTML={targetDisplayNameHtml} /></bdi>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HotKeys handlers={this.getHandlers()}>
|
<HotKeys handlers={this.getHandlers()}>
|
||||||
|
@ -403,7 +403,7 @@ class Notification extends ImmutablePureComponent {
|
||||||
const { notification } = this.props;
|
const { notification } = this.props;
|
||||||
const account = notification.get('account');
|
const account = notification.get('account');
|
||||||
const displayNameHtml = { __html: account.get('display_name_html') };
|
const displayNameHtml = { __html: account.get('display_name_html') };
|
||||||
const link = <bdi><Link className='notification__display-name' href={`/@${account.get('acct')}`} title={account.get('acct')} to={`/@${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>;
|
const link = <bdi><Permalink className='notification__display-name' href={`/@${account.get('acct')}`} title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>;
|
||||||
|
|
||||||
switch(notification.get('type')) {
|
switch(notification.get('type')) {
|
||||||
case 'follow':
|
case 'follow':
|
||||||
|
|
|
@ -184,7 +184,7 @@ class Footer extends ImmutablePureComponent {
|
||||||
<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='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')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} counter={status.get('reblogs_count')} />
|
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} counter={status.get('reblogs_count')} />
|
||||||
<IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} counter={status.get('favourites_count')} />
|
<IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} counter={status.get('favourites_count')} />
|
||||||
{withOpenButton && <IconButton className='status__action-bar-button' title={intl.formatMessage(messages.open)} icon='external-link' onClick={this.handleOpenClick} href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} />}
|
{withOpenButton && <IconButton className='status__action-bar-button' title={intl.formatMessage(messages.open)} icon='external-link' onClick={this.handleOpenClick} href={status.get('url')} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,7 +267,7 @@ class DetailedStatus extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div style={outerStyle}>
|
<div style={outerStyle}>
|
||||||
<div ref={this.setRef} className={classNames('detailed-status', `detailed-status-${status.get('visibility')}`, { compact })}>
|
<div ref={this.setRef} className={classNames('detailed-status', `detailed-status-${status.get('visibility')}`, { compact })}>
|
||||||
<a href={`/@${status.getIn(['account', 'acct'])}`} onClick={this.handleAccountClick} className='detailed-status__display-name'>
|
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
|
||||||
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={46} /></div>
|
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={46} /></div>
|
||||||
<DisplayName account={status.get('account')} localDomain={this.props.domain} />
|
<DisplayName account={status.get('account')} localDomain={this.props.domain} />
|
||||||
</a>
|
</a>
|
||||||
|
@ -282,7 +282,7 @@ class DetailedStatus extends ImmutablePureComponent {
|
||||||
{status.get('activity_pub_type') === 'Article' ? null : media}
|
{status.get('activity_pub_type') === 'Article' ? null : media}
|
||||||
|
|
||||||
<div className='detailed-status__meta'>
|
<div className='detailed-status__meta'>
|
||||||
<a className='detailed-status__datetime' href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} target='_blank' rel='noopener noreferrer'>
|
<a className='detailed-status__datetime' href={status.get('url')} 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' />
|
<FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
|
||||||
</a>{edited}{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink}{localOnly}
|
</a>{edited}{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink}{localOnly}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -98,12 +98,12 @@ class BoostModal extends ImmutablePureComponent {
|
||||||
<div className='boost-modal__container'>
|
<div className='boost-modal__container'>
|
||||||
<div className={classNames('status', `status-${status.get('visibility')}`, 'light')}>
|
<div className={classNames('status', `status-${status.get('visibility')}`, 'light')}>
|
||||||
<div className='status__info'>
|
<div className='status__info'>
|
||||||
<a href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||||
<span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span>
|
<span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span>
|
||||||
<RelativeTimestamp timestamp={status.get('created_at')} />
|
<RelativeTimestamp timestamp={status.get('created_at')} />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a onClick={this.handleAccountClick} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name'>
|
<a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
|
||||||
<div className='status__avatar'>
|
<div className='status__avatar'>
|
||||||
<Avatar account={status.get('account')} size={48} />
|
<Avatar account={status.get('account')} size={48} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,15 +4,16 @@ import { Link, withRouter } from 'react-router-dom';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { registrationsOpen, me } from 'mastodon/initial_state';
|
import { registrationsOpen, me } from 'mastodon/initial_state';
|
||||||
import Avatar from 'mastodon/components/avatar';
|
import Avatar from 'mastodon/components/avatar';
|
||||||
|
import Permalink from 'mastodon/components/permalink';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
const Account = connect(state => ({
|
const Account = connect(state => ({
|
||||||
account: state.getIn(['accounts', me]),
|
account: state.getIn(['accounts', me]),
|
||||||
}))(({ account }) => (
|
}))(({ account }) => (
|
||||||
<Link to={`/@${account.get('acct')}`} title={account.get('acct')}>
|
<Permalink href={account.get('url')} to={`/@${account.get('acct')}`} title={account.get('acct')}>
|
||||||
<Avatar account={account} size={35} />
|
<Avatar account={account} size={35} />
|
||||||
</Link>
|
</Permalink>
|
||||||
));
|
));
|
||||||
|
|
||||||
export default @withRouter
|
export default @withRouter
|
||||||
|
|
|
@ -1939,6 +1939,9 @@ a.account__display-name {
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permalink {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue