Skip to content

Commit

Permalink
Use Permalink with href instead of Link to jump to remote pages
Browse files Browse the repository at this point in the history
  • Loading branch information
ushitora-anqou committed Sep 24, 2023
1 parent 3b4ae57 commit ef28f3c
Showing 12 changed files with 88 additions and 36 deletions.
7 changes: 4 additions & 3 deletions app/javascript/mastodon/components/account.jsx
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';

import classNames from 'classnames';
import { Link } from 'react-router-dom';


import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@@ -19,6 +19,7 @@ import Button from './button';
import { FollowersCounter } from './counters';
import { DisplayName } from './display_name';
import { IconButton } from './icon_button';
import Permalink from './permalink';
import { RelativeTimestamp } from './relative_timestamp';

const messages = defineMessages({
@@ -151,7 +152,7 @@ class Account extends ImmutablePureComponent {
return (
<div className={classNames('account', { 'account--minimal': minimal })}>
<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>
@@ -164,7 +165,7 @@ class Account extends ImmutablePureComponent {
</div>
)}
</div>
</Link>
</Permalink>

{!minimal && (
<div className='account__relationship'>
12 changes: 8 additions & 4 deletions app/javascript/mastodon/components/hashtag.jsx
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ import { Component } from 'react';
import { FormattedMessage } from 'react-intl';

import classNames from 'classnames';
import { Link } from 'react-router-dom';


import ImmutablePropTypes from 'react-immutable-proptypes';

@@ -14,6 +14,8 @@ import { Sparklines, SparklinesCurve } from 'react-sparklines';
import { ShortNumber } from 'mastodon/components/short_number';
import { Skeleton } from 'mastodon/components/skeleton';

import Permalink from './permalink';

class SilentErrorBoundary extends Component {

static propTypes = {
@@ -58,6 +60,7 @@ export const accountsCountRenderer = (displayNumber, pluralReady) => (
export const ImmutableHashtag = ({ hashtag }) => (
<Hashtag
name={hashtag.get('name')}
href={hashtag.get('url')}
to={`/tags/${hashtag.get('name')}`}
people={hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1}
// @ts-expect-error
@@ -70,12 +73,12 @@ ImmutableHashtag.propTypes = {
};

// @ts-expect-error
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='trends__item__name'>
<Link to={to}>
<Permalink href={href} to={to}>
{name ? <>#<span>{name}</span></> : <Skeleton width={50} />}
</Link>
</Permalink>

{description ? (
<span>{description}</span>
@@ -104,6 +107,7 @@ const Hashtag = ({ name, to, people, uses, history, className, description, with

Hashtag.propTypes = {
name: PropTypes.string,
href: PropTypes.string,
to: PropTypes.string,
people: PropTypes.number,
description: PropTypes.node,
40 changes: 40 additions & 0 deletions app/javascript/mastodon/components/permalink.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import PropTypes from 'prop-types';
import React from 'react';

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>
);
}

}
8 changes: 4 additions & 4 deletions app/javascript/mastodon/components/status.jsx
Original file line number Diff line number Diff line change
@@ -417,7 +417,7 @@ class Status extends ImmutablePureComponent {
prepend = (
<div className='status__prepend'>
<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>
);

@@ -438,7 +438,7 @@ class Status extends ImmutablePureComponent {
prepend = (
<div className='status__prepend'>
<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>
);
}
@@ -558,12 +558,12 @@ class Status extends ImmutablePureComponent {

{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
<div onClick={this.handleClick} 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>
<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 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'>
{statusAvatar}
</div>
8 changes: 5 additions & 3 deletions app/javascript/mastodon/components/status_content.jsx
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import { PureComponent } from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';

import classnames from 'classnames';
import { Link } from 'react-router-dom';


import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
@@ -13,6 +13,8 @@ import { Icon } from 'mastodon/components/icon';
import PollContainer from 'mastodon/containers/poll_container';
import { autoPlayGif, languages as preloadedLanguages } from 'mastodon/initial_state';

import Permalink from './permalink';

const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top)

/**
@@ -270,9 +272,9 @@ class StatusContent extends PureComponent {
let mentionsPlaceholder = '';

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>
</Link>
</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' />;
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { FormattedMessage } from 'react-intl';

import { Link } from 'react-router-dom';

import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';

import { AvatarOverlay } from '../../../components/avatar_overlay';
import { DisplayName } from '../../../components/display_name';
import Permalink from '../../../components/permalink';

export default class MovedNote extends ImmutablePureComponent {

@@ -25,12 +25,12 @@ export default class MovedNote extends ImmutablePureComponent {
</div>

<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>
<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>
);
Original file line number Diff line number Diff line change
@@ -2,12 +2,12 @@ import PropTypes from 'prop-types';

import { FormattedMessage } from 'react-intl';

import { Link } from 'react-router-dom';

import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';

import { Avatar } from '../../../components/avatar';
import Permalink from '../../../components/permalink';

import ActionBar from './action_bar';

@@ -23,16 +23,16 @@ export default class NavigationBar extends ImmutablePureComponent {
const username = this.props.account.get('acct')
return (
<div className='navigation-bar'>
<Link to={`/@${username}`}>
<Permalink href={this.props.account.get('url')} to={`/@${username}`}>
<span style={{ display: 'none' }}>{username}</span>
<Avatar account={this.props.account} size={46} />
</Link>
</Permalink>

<div className='navigation-bar__profile'>
<span>
<Link to={`/@${username}`}>
<Permalink href={this.props.account.get('url')} to={`/@${username}`}>
<strong className='navigation-bar__profile-account'>@{username}</strong>
</Link>
</Permalink>
</span>

<span>
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';

import classNames from 'classnames';
import { Link } from 'react-router-dom';


import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@@ -13,6 +13,7 @@ import { HotKeys } from 'react-hotkeys';
import AttachmentList from 'mastodon/components/attachment_list';
import AvatarComposite from 'mastodon/components/avatar_composite';
import { IconButton } from 'mastodon/components/icon_button';
import Permalink from 'mastodon/components/permalink';
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
import StatusContent from 'mastodon/components/status_content';
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
@@ -136,7 +137,7 @@ class Conversation extends ImmutablePureComponent {

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')}`} ref={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 = {
reply: this.handleReply,
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';

import classNames from 'classnames';
import { Link } from 'react-router-dom';


import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@@ -19,6 +19,7 @@ import { openModal } from 'mastodon/actions/modal';
import { Avatar } from 'mastodon/components/avatar';
import Button from 'mastodon/components/button';
import { DisplayName } from 'mastodon/components/display_name';
import Permalink from 'mastodon/components/permalink';
import { ShortNumber } from 'mastodon/components/short_number';
import { autoPlayGif, me, unfollowModal } from 'mastodon/initial_state';
import { makeGetAccount } from 'mastodon/selectors';
@@ -174,7 +175,7 @@ class AccountCard extends ImmutablePureComponent {

return (
<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'>
<img
src={
@@ -188,7 +189,7 @@ class AccountCard extends ImmutablePureComponent {
<div className='account-card__title__avatar'><Avatar account={account} size={56} /></div>
<DisplayName account={account} />
</div>
</Link>
</Permalink>

{account.get('note').length > 0 && (
<div
Original file line number Diff line number Diff line change
@@ -2,14 +2,14 @@ import PropTypes from 'prop-types';

import { defineMessages, injectIntl } from 'react-intl';

import { Link } from 'react-router-dom';

import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';

import { Avatar } from 'mastodon/components/avatar';
import { DisplayName } from 'mastodon/components/display_name';
import { IconButton } from 'mastodon/components/icon_button';
import Permalink from 'mastodon/components/permalink';

const messages = defineMessages({
authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
@@ -44,10 +44,10 @@ class FollowRequest extends ImmutablePureComponent {
return (
<div className='account'>
<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>
<DisplayName account={account} />
</Link>
</Permalink>

<div className='account__relationship'>
<IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} />
Original file line number Diff line number Diff line change
@@ -3,14 +3,15 @@ import PropTypes from 'prop-types';
import { injectIntl, FormattedMessage, defineMessages } from 'react-intl';

import classNames from 'classnames';
import { Link } from 'react-router-dom';


import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';

import { HotKeys } from 'react-hotkeys';

import { Icon } from 'mastodon/components/icon';
import Permalink from 'mastodon/components/permalink';
import AccountContainer from 'mastodon/containers/account_container';
import StatusContainer from 'mastodon/containers/status_container';
import { me } from 'mastodon/initial_state';
@@ -398,7 +399,7 @@ class Notification extends ImmutablePureComponent {

const targetAccount = report.get('target_account');
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' href={targetAccount.get('url')} title={targetAccount.get('acct')} to={`/@${targetAccount.get('acct')}`} dangerouslySetInnerHTML={targetDisplayNameHtml} /></bdi>;

return (
<HotKeys handlers={this.getHandlers()}>
@@ -423,7 +424,7 @@ class Notification extends ImmutablePureComponent {
const { notification } = this.props;
const account = notification.get('account');
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('url')} title={account.get('acct')} to={`/@${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>;

switch(notification.get('type')) {
case 'follow':
Loading

0 comments on commit ef28f3c

Please # to comment.