Merge branch 'master' into glitch-soc/merge-upstream
Conflicts: - README.md - app/helpers/statuses_helper.rb Upstream moved account helpers to their own file, we had extra helpers there, moved too. - app/lib/sanitize_config.rb - app/models/user.rb - app/serializers/initial_state_serializer.rb - config/locales/simple_form.en.yml - spec/lib/sanitize_config_spec.rb
This commit is contained in:
@@ -253,7 +253,7 @@ class Header extends ImmutablePureComponent {
|
||||
|
||||
<div className='account__header__bar'>
|
||||
<div className='account__header__tabs'>
|
||||
<a className='avatar' href={account.get('url')} rel='noopener' target='_blank'>
|
||||
<a className='avatar' href={account.get('url')} rel='noopener noreferrer' target='_blank'>
|
||||
<Avatar account={account} size={90} />
|
||||
</a>
|
||||
|
||||
@@ -282,10 +282,10 @@ class Header extends ImmutablePureComponent {
|
||||
<dt dangerouslySetInnerHTML={{ __html: proof.get('provider') }} />
|
||||
|
||||
<dd className='verified'>
|
||||
<a href={proof.get('proof_url')} target='_blank' rel='noopener'><span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
|
||||
<a href={proof.get('proof_url')} target='_blank' rel='noopener noreferrer'><span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
|
||||
<Icon id='check' className='verified__mark' />
|
||||
</span></a>
|
||||
<a href={proof.get('profile_url')} target='_blank' rel='noopener'><span dangerouslySetInnerHTML={{ __html: ' '+proof.get('provider_username') }} /></a>
|
||||
<a href={proof.get('profile_url')} target='_blank' rel='noopener noreferrer'><span dangerouslySetInnerHTML={{ __html: ' '+proof.get('provider_username') }} /></a>
|
||||
</dd>
|
||||
</dl>
|
||||
))}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { decode } from 'blurhash';
|
||||
import classNames from 'classnames';
|
||||
import Icon from 'mastodon/components/icon';
|
||||
import { autoPlayGif, displayMedia } from 'mastodon/initial_state';
|
||||
import classNames from 'classnames';
|
||||
import { decode } from 'blurhash';
|
||||
import { isIOS } from 'mastodon/is_mobile';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
export default class MediaItem extends ImmutablePureComponent {
|
||||
|
||||
@@ -151,7 +151,7 @@ export default class MediaItem extends ImmutablePureComponent {
|
||||
|
||||
return (
|
||||
<div className='account-gallery__item' style={{ width, height }}>
|
||||
<a className='media-gallery__item-thumbnail' href={status.get('url')} target='_blank' onClick={this.handleClick} title={title}>
|
||||
<a className='media-gallery__item-thumbnail' href={status.get('url')} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'>
|
||||
<canvas width={32} height={32} ref={this.setCanvasRef} className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })} />
|
||||
{visible && thumbnail}
|
||||
{!visible && icon}
|
||||
|
||||
@@ -12,6 +12,7 @@ const messages = defineMessages({
|
||||
pause: { id: 'video.pause', defaultMessage: 'Pause' },
|
||||
mute: { id: 'video.mute', defaultMessage: 'Mute sound' },
|
||||
unmute: { id: 'video.unmute', defaultMessage: 'Unmute sound' },
|
||||
download: { id: 'video.download', defaultMessage: 'Download file' },
|
||||
});
|
||||
|
||||
export default @injectIntl
|
||||
@@ -202,6 +203,7 @@ class Audio extends React.PureComponent {
|
||||
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
|
||||
|
||||
<div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
|
||||
|
||||
<div className='video-player__volume__current' style={{ width: `${volumeWidth}px` }} />
|
||||
|
||||
<span
|
||||
@@ -217,6 +219,14 @@ class Audio extends React.PureComponent {
|
||||
<span className='video-player__time-total'>{formatTime(this.state.duration || Math.floor(this.props.duration))}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className='video-player__buttons right'>
|
||||
<button type='button' aria-label={intl.formatMessage(messages.download)}>
|
||||
<a className='video-player__download__icon' href={this.props.src} download>
|
||||
<Icon id={'download'} fixedWidth />
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import Toggle from 'react-toggle';
|
||||
import AsyncSelect from 'react-select/lib/Async';
|
||||
import AsyncSelect from 'react-select/async';
|
||||
|
||||
const messages = defineMessages({
|
||||
placeholder: { id: 'hashtag.column_settings.select.placeholder', defaultMessage: 'Enter hashtags…' },
|
||||
|
||||
@@ -148,7 +148,7 @@ export default class Card extends React.PureComponent {
|
||||
const horizontal = (!compact && card.get('width') > card.get('height') && (card.get('width') + 100 >= width)) || card.get('type') !== 'link' || embedded;
|
||||
const interactive = card.get('type') !== 'link';
|
||||
const className = classnames('status-card', { horizontal, compact, interactive });
|
||||
const title = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
|
||||
const title = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener noreferrer' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
|
||||
const ratio = card.get('width') / card.get('height');
|
||||
const height = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
|
||||
|
||||
@@ -180,7 +180,7 @@ export default class Card extends React.PureComponent {
|
||||
<div className='status-card__actions'>
|
||||
<div>
|
||||
<button onClick={this.handleEmbedClick}><Icon id={iconVariant} /></button>
|
||||
{horizontal && <a href={card.get('url')} target='_blank' rel='noopener'><Icon id='external-link' /></a>}
|
||||
{horizontal && <a href={card.get('url')} target='_blank' rel='noopener noreferrer'><Icon id='external-link' /></a>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -208,7 +208,7 @@ export default class Card extends React.PureComponent {
|
||||
}
|
||||
|
||||
return (
|
||||
<a href={card.get('url')} className={className} target='_blank' rel='noopener' ref={this.setRef}>
|
||||
<a href={card.get('url')} className={className} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
|
||||
{embed}
|
||||
{description}
|
||||
</a>
|
||||
|
||||
@@ -156,7 +156,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
if (status.get('application')) {
|
||||
applicationLink = <span> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener'>{status.getIn(['application', 'name'])}</a></span>;
|
||||
applicationLink = <span> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener noreferrer'>{status.getIn(['application', 'name'])}</a></span>;
|
||||
}
|
||||
|
||||
if (status.get('visibility') === 'direct') {
|
||||
@@ -220,7 +220,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
||||
{media}
|
||||
|
||||
<div className='detailed-status__meta'>
|
||||
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
|
||||
<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' />
|
||||
</a>{applicationLink} · {reblogLink} · {favouriteLink}
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@ export default class ActionsModal extends ImmutablePureComponent {
|
||||
|
||||
return (
|
||||
<li key={`${text}-${i}`}>
|
||||
<a href={href} target='_blank' rel='noopener' onClick={this.props.onClick} data-index={i} className={classNames({ active })}>
|
||||
<a href={href} target='_blank' rel='noopener noreferrer' onClick={this.props.onClick} data-index={i} className={classNames({ active })}>
|
||||
{icon && <IconButton title={text} icon={icon} role='presentation' tabIndex='-1' inverted />}
|
||||
<div>
|
||||
<div className={classNames({ 'actions-modal__item-label': !!meta })}>{text}</div>
|
||||
@@ -42,7 +42,7 @@ export default class ActionsModal extends ImmutablePureComponent {
|
||||
<div className='status light'>
|
||||
<div className='boost-modal__status-header'>
|
||||
<div className='boost-modal__status-time'>
|
||||
<a href={this.props.status.get('url')} className='status__relative-time' target='_blank' rel='noopener'>
|
||||
<a href={this.props.status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||
<RelativeTimestamp timestamp={this.props.status.get('created_at')} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -61,7 +61,7 @@ class BoostModal extends ImmutablePureComponent {
|
||||
<div className='status light'>
|
||||
<div className='boost-modal__status-header'>
|
||||
<div className='boost-modal__status-time'>
|
||||
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
|
||||
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
|
||||
</div>
|
||||
|
||||
<a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
|
||||
|
||||
@@ -182,7 +182,7 @@ class ColumnsArea extends ImmutablePureComponent {
|
||||
const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <Link key='floating-action-button' to='/statuses/new' className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}><Icon id='pencil' /></Link>;
|
||||
|
||||
const content = columnIndex !== -1 ? (
|
||||
<ReactSwipeableViews key='content' index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }}>
|
||||
<ReactSwipeableViews key='content' hysteresis={0.2} threshold={15} index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }}>
|
||||
{links.map(this.renderView)}
|
||||
</ReactSwipeableViews>
|
||||
) : (
|
||||
|
||||
@@ -62,7 +62,7 @@ class LinkFooter extends React.PureComponent {
|
||||
<FormattedMessage
|
||||
id='getting_started.open_source_notice'
|
||||
defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
|
||||
values={{ github: <span><a href={source_url} rel='noopener' target='_blank'>{repository}</a> (v{version})</span> }}
|
||||
values={{ github: <span><a href={source_url} rel='noopener noreferrer' target='_blank'>{repository}</a> (v{version})</span> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,7 @@ const messages = defineMessages({
|
||||
close: { id: 'video.close', defaultMessage: 'Close video' },
|
||||
fullscreen: { id: 'video.fullscreen', defaultMessage: 'Full screen' },
|
||||
exit_fullscreen: { id: 'video.exit_fullscreen', defaultMessage: 'Exit full screen' },
|
||||
download: { id: 'video.download', defaultMessage: 'Download file' },
|
||||
});
|
||||
|
||||
export const formatTime = secondsNum => {
|
||||
@@ -470,6 +471,7 @@ class Video extends React.PureComponent {
|
||||
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
|
||||
|
||||
<div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
|
||||
|
||||
<div className='video-player__volume__current' style={{ width: `${volumeWidth}px` }} />
|
||||
<span
|
||||
className={classNames('video-player__volume__handle')}
|
||||
@@ -493,7 +495,13 @@ class Video extends React.PureComponent {
|
||||
{(!onCloseVideo && !editable) && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
|
||||
{(!fullscreen && onOpenVideo) && <button type='button' aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><Icon id='expand' fixedWidth /></button>}
|
||||
{onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><Icon id='compress' fixedWidth /></button>}
|
||||
<button type='button' aria-label={intl.formatMessage(messages.download)}>
|
||||
<a className='video-player__download__icon' href={this.props.src} download>
|
||||
<Icon id={'download'} fixedWidth />
|
||||
</a>
|
||||
</button>
|
||||
<button type='button' aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} onClick={this.toggleFullscreen}><Icon id={fullscreen ? 'compress' : 'arrows-alt'} fixedWidth /></button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user