Merge commit 'c8181eb0a4' into kb_migration

This commit is contained in:
KMY 2023-05-09 15:39:21 +09:00
commit ba3f60ba63
153 changed files with 426 additions and 366 deletions

View file

@ -4,6 +4,7 @@ module.exports = {
extends: [ extends: [
'eslint:recommended', 'eslint:recommended',
'plugin:react/recommended', 'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended', 'plugin:jsx-a11y/recommended',
'plugin:import/recommended', 'plugin:import/recommended',
'plugin:promise/recommended', 'plugin:promise/recommended',
@ -102,6 +103,7 @@ module.exports = {
{ {
vars: 'all', vars: 'all',
args: 'after-used', args: 'after-used',
destructuredArrayIgnorePattern: '^_',
ignoreRestSiblings: true, ignoreRestSiblings: true,
}, },
], ],
@ -208,6 +210,9 @@ module.exports = {
], ],
}, },
], ],
'import/no-amd': 'error',
'import/no-commonjs': 'error',
'import/no-import-module-exports': 'error',
'import/no-webpack-loader-syntax': 'error', 'import/no-webpack-loader-syntax': 'error',
'promise/always-return': 'off', 'promise/always-return': 'off',
@ -255,6 +260,7 @@ module.exports = {
'*.config.js', '*.config.js',
'.*rc.js', '.*rc.js',
'ide-helper.js', 'ide-helper.js',
'config/webpack/**/*',
], ],
env: { env: {
@ -264,6 +270,10 @@ module.exports = {
parserOptions: { parserOptions: {
sourceType: 'script', sourceType: 'script',
}, },
rules: {
'import/no-commonjs': 'off',
},
}, },
{ {
files: [ files: [
@ -275,6 +285,7 @@ module.exports = {
'eslint:recommended', 'eslint:recommended',
'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended',
'plugin:react/recommended', 'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended', 'plugin:jsx-a11y/recommended',
'plugin:import/recommended', 'plugin:import/recommended',
'plugin:import/typescript', 'plugin:import/typescript',
@ -286,6 +297,12 @@ module.exports = {
'@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-explicit-any': 'off',
'jsdoc/require-jsdoc': 'off', 'jsdoc/require-jsdoc': 'off',
// Those rules set stricter rules for TS files
// to enforce better practices when converting from JS
'import/no-default-export': 'warn',
'react/prefer-stateless-function': 'warn',
'react/function-component-definition': ['error', { namedComponents: 'arrow-function' }],
}, },
}, },
{ {
@ -298,5 +315,13 @@ module.exports = {
jest: true, jest: true,
}, },
}, },
{
files: [
'streaming/**/*',
],
rules: {
'import/no-commonjs': 'off',
},
},
], ],
}; };

View file

@ -1,10 +1,11 @@
import { createAction } from '@reduxjs/toolkit'; import { createAction } from '@reduxjs/toolkit';
import type { LayoutType } from '../is_mobile';
export const focusApp = createAction('APP_FOCUS'); export const focusApp = createAction('APP_FOCUS');
export const unfocusApp = createAction('APP_UNFOCUS'); export const unfocusApp = createAction('APP_UNFOCUS');
type ChangeLayoutPayload = { type ChangeLayoutPayload = {
layout: 'mobile' | 'single-column' | 'multi-column'; layout: LayoutType;
}; };
export const changeLayout = export const changeLayout =
createAction<ChangeLayoutPayload>('APP_LAYOUT_CHANGE'); createAction<ChangeLayoutPayload>('APP_LAYOUT_CHANGE');

View file

@ -1,6 +1,6 @@
import api from '../api'; import api from '../api';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import compareId from '../compare_id'; import { compareId } from '../compare_id';
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
export const MARKERS_FETCH_REQUEST = 'MARKERS_FETCH_REQUEST'; export const MARKERS_FETCH_REQUEST = 'MARKERS_FETCH_REQUEST';

View file

@ -13,7 +13,7 @@ import { defineMessages } from 'react-intl';
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
import { unescapeHTML } from '../utils/html'; import { unescapeHTML } from '../utils/html';
import { usePendingItems as preferPendingItems } from 'mastodon/initial_state'; import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
import compareId from 'mastodon/compare_id'; import { compareId } from 'mastodon/compare_id';
import { requestNotificationPermission } from '../utils/notifications'; import { requestNotificationPermission } from '../utils/notifications';
import { STATUS_EMOJI_REACTION_UPDATE } from './statuses'; import { STATUS_EMOJI_REACTION_UPDATE } from './statuses';

View file

@ -52,8 +52,10 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
/** /**
* @param {function(Function, Function): void} fallback * @param {function(Function, Function): void} fallback
*/ */
const useFallback = fallback => { const useFallback = fallback => {
fallback(dispatch, () => { fallback(dispatch, () => {
// eslint-disable-next-line react-hooks/rules-of-hooks -- this is not a react hook
pollingId = setTimeout(() => useFallback(fallback), 20000 + randomUpTo(20000)); pollingId = setTimeout(() => useFallback(fallback), 20000 + randomUpTo(20000));
}); });
}; };

View file

@ -2,7 +2,7 @@ import { importFetchedStatus, importFetchedStatuses } from './importer';
import { submitMarkers } from './markers'; import { submitMarkers } from './markers';
import api, { getLinks } from 'mastodon/api'; import api, { getLinks } from 'mastodon/api';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
import compareId from 'mastodon/compare_id'; import { compareId } from 'mastodon/compare_id';
import { usePendingItems as preferPendingItems } from 'mastodon/initial_state'; import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE'; export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';

View file

@ -1,7 +1,7 @@
import Rails from '@rails/ujs'; import Rails from '@rails/ujs';
import 'font-awesome/css/font-awesome.css';
export function start() { export function start() {
require('font-awesome/css/font-awesome.css');
require.context('../images/', true); require.context('../images/', true);
try { try {

View file

@ -1,4 +1,4 @@
export default function compareId (id1: string, id2: string) { export function compareId (id1: string, id2: string) {
if (id1 === id2) { if (id1 === id2) {
return 0; return 0;
} }

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import renderer from 'react-test-renderer'; import renderer from 'react-test-renderer';
import { fromJS } from 'immutable'; import { fromJS } from 'immutable';
import Avatar from '../avatar'; import { Avatar } from '../avatar';
describe('<Avatar />', () => { describe('<Avatar />', () => {
const account = fromJS({ const account = fromJS({

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import renderer from 'react-test-renderer'; import renderer from 'react-test-renderer';
import { fromJS } from 'immutable'; import { fromJS } from 'immutable';
import AvatarOverlay from '../avatar_overlay'; import { AvatarOverlay } from '../avatar_overlay';
describe('<AvatarOverlay', () => { describe('<AvatarOverlay', () => {
const account = fromJS({ const account = fromJS({

View file

@ -1,19 +1,19 @@
import React from 'react'; 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 Avatar from './avatar'; import { Avatar } from './avatar';
import DisplayName from './display_name'; import DisplayName from './display_name';
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'; import { Link } from 'react-router-dom';
import { counterRenderer } from 'mastodon/components/common_counter'; import { counterRenderer } from 'mastodon/components/common_counter';
import ShortNumber from 'mastodon/components/short_number'; import ShortNumber from 'mastodon/components/short_number';
import classNames from 'classnames'; import classNames from 'classnames';
import VerifiedBadge from 'mastodon/components/verified_badge'; import { VerifiedBadge } from 'mastodon/components/verified_badge';
const messages = defineMessages({ const messages = defineMessages({
follow: { id: 'account.follow', defaultMessage: 'Follow' }, follow: { id: 'account.follow', defaultMessage: 'Follow' },
@ -152,7 +152,7 @@ class Account extends ImmutablePureComponent {
const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at')); const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at'));
if (firstVerifiedField) { if (firstVerifiedField) {
verification = <>· <VerifiedBadge link={firstVerifiedField.get('value')} verifiedAt={firstVerifiedField.get('verified_at')} /></>; verification = <>· <VerifiedBadge link={firstVerifiedField.get('value')} /></>;
} }
return ( return (

View file

@ -54,5 +54,3 @@ export const AnimatedNumber: React.FC<Props> = ({
</TransitionMotion> </TransitionMotion>
); );
}; };
export default AnimatedNumber;

View file

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const filename = url => url.split('/').pop().split('#')[0].split('?')[0]; const filename = url => url.split('/').pop().split('#')[0].split('?')[0];

View file

@ -45,5 +45,3 @@ export const Avatar: React.FC<Props> = ({
</div> </div>
); );
}; };
export default Avatar;

View file

@ -2,7 +2,7 @@ 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 { autoPlayGif } from '../initial_state'; import { autoPlayGif } from '../initial_state';
import Avatar from './avatar'; import { Avatar } from './avatar';
export default class AvatarComposite extends React.PureComponent { export default class AvatarComposite extends React.PureComponent {

View file

@ -47,5 +47,3 @@ export const AvatarOverlay: React.FC<Props> = ({
</div> </div>
); );
}; };
export default AvatarOverlay;

View file

@ -9,13 +9,13 @@ type Props = {
children?: never; children?: never;
[key: string]: any; [key: string]: any;
} }
function Blurhash({ const Blurhash: React.FC<Props> = ({
hash, hash,
width = 32, width = 32,
height = width, height = width,
dummy = false, dummy = false,
...canvasProps ...canvasProps
}: Props) { }) => {
const canvasRef = useRef<HTMLCanvasElement>(null); const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => { useEffect(() => {
@ -40,6 +40,8 @@ function Blurhash({
return ( return (
<canvas {...canvasProps} ref={canvasRef} width={width} height={height} /> <canvas {...canvasProps} ref={canvasRef} width={width} height={height} />
); );
} };
export default React.memo(Blurhash); const MemoizedBlurhash = React.memo(Blurhash);
export { MemoizedBlurhash as Blurhash };

View file

@ -1,9 +1,7 @@
import React from 'react'; import React from 'react';
const Check = () => ( export const Check: React.FC = () => (
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='currentColor'> <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='currentColor'>
<path fillRule='evenodd' d='M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z' clipRule='evenodd' /> <path fillRule='evenodd' d='M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z' clipRule='evenodd' />
</svg> </svg>
); );
export default Check;

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
export default class ColumnBackButton extends React.PureComponent { export default class ColumnBackButton extends React.PureComponent {

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import ColumnBackButton from './column_back_button'; import ColumnBackButton from './column_back_button';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
export default class ColumnBackButtonSlim extends ColumnBackButton { export default class ColumnBackButtonSlim extends ColumnBackButton {

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({ const messages = defineMessages({
show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' }, show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import IconButton from './icon_button'; import { IconButton } from './icon_button';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { injectIntl, defineMessages } from 'react-intl'; import { injectIntl, defineMessages } from 'react-intl';
import { bannerSettings } from 'mastodon/settings'; import { bannerSettings } from 'mastodon/settings';

View file

@ -1,43 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import IconButton from './icon_button';
import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
const messages = defineMessages({
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
});
class Account extends ImmutablePureComponent {
static propTypes = {
domain: PropTypes.string,
onUnblockDomain: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleDomainUnblock = () => {
this.props.onUnblockDomain(this.props.domain);
};
render () {
const { domain, intl } = this.props;
return (
<div className='domain'>
<div className='domain__wrapper'>
<span className='domain__domain-name'>
<strong>{domain}</strong>
</span>
<div className='domain__buttons'>
<IconButton active icon='unlock' title={intl.formatMessage(messages.unblockDomain, { domain })} onClick={this.handleDomainUnblock} />
</div>
</div>
</div>
);
}
}
export default injectIntl(Account);

View file

@ -0,0 +1,42 @@
import React, { useCallback } from 'react';
import { IconButton } from './icon_button';
import { InjectedIntl, defineMessages, injectIntl } from 'react-intl';
const messages = defineMessages({
unblockDomain: {
id: 'account.unblock_domain',
defaultMessage: 'Unblock domain {domain}',
},
});
type Props = {
domain: string;
onUnblockDomain: (domain: string) => void;
intl: InjectedIntl;
};
const _Domain: React.FC<Props> = ({ domain, onUnblockDomain, intl }) => {
const handleDomainUnblock = useCallback(() => {
onUnblockDomain(domain);
}, [domain, onUnblockDomain]);
return (
<div className='domain'>
<div className='domain__wrapper'>
<span className='domain__domain-name'>
<strong>{domain}</strong>
</span>
<div className='domain__buttons'>
<IconButton
active
icon='unlock'
title={intl.formatMessage(messages.unblockDomain, { domain })}
onClick={handleDomainUnblock}
/>
</div>
</div>
</div>
);
};
export const Domain = injectIntl(_Domain);

View file

@ -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 IconButton from './icon_button'; import { IconButton } from './icon_button';
import Overlay from 'react-overlays/Overlay'; import Overlay from 'react-overlays/Overlay';
import { supportsPassiveEvents } from 'detect-passive-events'; import { supportsPassiveEvents } from 'detect-passive-events';
import classNames from 'classnames'; import classNames from 'classnames';

View file

@ -1,11 +1,11 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl } from 'react-intl'; import { FormattedMessage, injectIntl } from 'react-intl';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import DropdownMenu from './containers/dropdown_menu_container'; import DropdownMenu from './containers/dropdown_menu_container';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { openModal } from 'mastodon/actions/modal'; import { openModal } from 'mastodon/actions/modal';
import RelativeTimestamp from 'mastodon/components/relative_timestamp'; import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
import InlineAccount from 'mastodon/components/inline_account'; import InlineAccount from 'mastodon/components/inline_account';
const mapDispatchToProps = (dispatch, { statusId }) => ({ const mapDispatchToProps = (dispatch, { statusId }) => ({

View file

@ -64,5 +64,3 @@ export const GIFV: React.FC<Props> = ({
</div> </div>
); );
}; };
export default GIFV;

View file

@ -5,9 +5,7 @@ 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 { Link } from 'react-router-dom';
// @ts-expect-error
import ShortNumber from 'mastodon/components/short_number'; import ShortNumber from 'mastodon/components/short_number';
// @ts-expect-error
import Skeleton from 'mastodon/components/skeleton'; import Skeleton from 'mastodon/components/skeleton';
import classNames from 'classnames'; import classNames from 'classnames';

View file

@ -10,5 +10,3 @@ type Props = {
} }
export const Icon: React.FC<Props> = ({ id, className, fixedWidth, ...other }) => export const Icon: React.FC<Props> = ({ id, className, fixedWidth, ...other }) =>
<i className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} />; <i className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} />;
export default Icon;

View file

@ -30,7 +30,7 @@ type States = {
activate: boolean, activate: boolean,
deactivate: boolean, deactivate: boolean,
} }
export default class IconButton extends React.PureComponent<Props, States> { export class IconButton extends React.PureComponent<Props, States> {
static defaultProps = { static defaultProps = {
size: 18, size: 18,

View file

@ -9,12 +9,10 @@ type Props = {
issueBadge: boolean; issueBadge: boolean;
className: string; className: string;
} }
const IconWithBadge: React.FC<Props> = ({ id, count, issueBadge, className }) => ( export const IconWithBadge: React.FC<Props> = ({ id, count, issueBadge, className }) => (
<i className='icon-with-badge'> <i className='icon-with-badge'>
<Icon id={id} fixedWidth className={className} /> <Icon id={id} fixedWidth className={className} />
{count > 0 && <i className='icon-with-badge__badge'>{formatNumber(count)}</i>} {count > 0 && <i className='icon-with-badge__badge'>{formatNumber(count)}</i>}
{issueBadge && <i className='icon-with-badge__issue-badge' />} {issueBadge && <i className='icon-with-badge__issue-badge' />}
</i> </i>
); );
export default IconWithBadge;

View file

@ -1,33 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import Blurhash from './blurhash';
import classNames from 'classnames';
export default class Image extends React.PureComponent {
static propTypes = {
src: PropTypes.string,
srcSet: PropTypes.string,
blurhash: PropTypes.string,
className: PropTypes.string,
};
state = {
loaded: false,
};
handleLoad = () => this.setState({ loaded: true });
render () {
const { src, srcSet, blurhash, className } = this.props;
const { loaded } = this.state;
return (
<div className={classNames('image', { loaded }, className)} role='presentation'>
{blurhash && <Blurhash hash={blurhash} className='image__preview' />}
<img src={src} srcSet={srcSet} alt='' onLoad={this.handleLoad} />
</div>
);
}
}

View file

@ -0,0 +1,25 @@
import React, { useCallback, useState } from 'react';
import { Blurhash } from './blurhash';
import classNames from 'classnames';
type Props = {
src: string;
srcSet?: string;
blurhash?: string;
className?: string;
}
export const Image: React.FC<Props> = ({ src, srcSet, blurhash, className }) => {
const [loaded, setLoaded] = useState(false);
const handleLoad = useCallback(() => {
setLoaded(true);
}, [setLoaded]);
return (
<div className={classNames('image', { loaded }, className)} role='presentation'>
{blurhash && <Blurhash hash={blurhash} className='image__preview' />}
<img src={src} srcSet={srcSet} alt='' onLoad={handleLoad} />
</div>
);
};

View file

@ -2,7 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux'; 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';
const makeMapStateToProps = () => { const makeMapStateToProps = () => {
const getAccount = makeGetAccount(); const getAccount = makeGetAccount();

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { injectIntl, defineMessages } from 'react-intl'; import { injectIntl, defineMessages } from 'react-intl';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({ const messages = defineMessages({
load_more: { id: 'status.load_more', defaultMessage: 'Load more' }, load_more: { id: 'status.load_more', defaultMessage: 'Load more' },

View file

@ -2,12 +2,12 @@ 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 { is } from 'immutable'; import { is } from 'immutable';
import IconButton from './icon_button'; import { IconButton } from './icon_button';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import { autoPlayGif, cropImages, displayMedia, displayMediaExpand, useBlurhash } from '../initial_state'; import { autoPlayGif, cropImages, displayMedia, displayMediaExpand, useBlurhash } from '../initial_state';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import Blurhash from 'mastodon/components/blurhash'; import { Blurhash } from 'mastodon/components/blurhash';
const messages = defineMessages({ const messages = defineMessages({
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: '{number, plural, one {Hide image} other {Hide images}}' }, toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: '{number, plural, one {Hide image} other {Hide images}}' },

View file

@ -1,12 +1,10 @@
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
const NotSignedInIndicator = () => ( export const NotSignedInIndicator: React.FC = () => (
<div className='scrollable scrollable--flex'> <div className='scrollable scrollable--flex'>
<div className='empty-column-indicator'> <div className='empty-column-indicator'>
<FormattedMessage id='not_signed_in_indicator.not_signed_in' defaultMessage='You need to sign in to access this resource.' /> <FormattedMessage id='not_signed_in_indicator.not_signed_in' defaultMessage='You need to sign in to access this resource.' />
</div> </div>
</div> </div>
); );
export default NotSignedInIndicator;

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { removePictureInPicture } from 'mastodon/actions/picture_in_picture'; import { removePictureInPicture } from 'mastodon/actions/picture_in_picture';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';

View file

@ -8,8 +8,8 @@ import Motion from 'mastodon/features/ui/util/optional_motion';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import escapeTextContentForBrowser from 'escape-html'; import escapeTextContentForBrowser from 'escape-html';
import emojify from 'mastodon/features/emoji/emoji'; import emojify from 'mastodon/features/emoji/emoji';
import RelativeTimestamp from './relative_timestamp'; import { RelativeTimestamp } from './relative_timestamp';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({ const messages = defineMessages({
closed: { closed: {

View file

@ -1,35 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
export default class RadioButton extends React.PureComponent {
static propTypes = {
value: PropTypes.string.isRequired,
checked: PropTypes.bool,
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
label: PropTypes.node.isRequired,
};
render () {
const { name, value, checked, onChange, label } = this.props;
return (
<label className='radio-button'>
<input
name={name}
type='radio'
value={value}
checked={checked}
onChange={onChange}
/>
<span className={classNames('radio-button__input', { checked })} />
<span>{label}</span>
</label>
);
}
}

View file

@ -0,0 +1,28 @@
import React from 'react';
import classNames from 'classnames';
type Props = {
value: string;
checked: boolean;
name: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
label: React.ReactNode;
};
export const RadioButton: React.FC<Props> = ({ name, value, checked, onChange, label }) => {
return (
<label className='radio-button'>
<input
name={name}
type='radio'
value={value}
checked={checked}
onChange={onChange}
/>
<span className={classNames('radio-button__input', { checked })} />
<span>{label}</span>
</label>
);
};

View file

@ -200,4 +200,6 @@ class RelativeTimestamp extends React.Component<Props, States> {
} }
export default injectIntl(RelativeTimestamp); const RelativeTimestampWithIntl = injectIntl(RelativeTimestamp);
export { RelativeTimestampWithIntl as RelativeTimestamp };

View file

@ -8,6 +8,7 @@ import IntersectionObserverWrapper from '../features/ui/util/intersection_observ
import { throttle } from 'lodash'; import { throttle } from 'lodash';
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
import classNames from 'classnames'; import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../features/ui/util/fullscreen'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../features/ui/util/fullscreen';
import LoadingIndicator from './loading_indicator'; import LoadingIndicator from './loading_indicator';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -236,10 +237,10 @@ class ScrollableList extends PureComponent {
attachScrollListener () { attachScrollListener () {
if (this.props.bindToDocument) { if (this.props.bindToDocument) {
document.addEventListener('scroll', this.handleScroll); document.addEventListener('scroll', this.handleScroll);
document.addEventListener('wheel', this.handleWheel); document.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : undefined);
} else { } else {
this.node.addEventListener('scroll', this.handleScroll); this.node.addEventListener('scroll', this.handleScroll);
this.node.addEventListener('wheel', this.handleWheel); this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : undefined);
} }
} }

View file

@ -7,7 +7,7 @@ import ShortNumber from 'mastodon/components/short_number';
import Skeleton from 'mastodon/components/skeleton'; import Skeleton from 'mastodon/components/skeleton';
import Account from 'mastodon/containers/account_container'; import Account from 'mastodon/containers/account_container';
import { domain } from 'mastodon/initial_state'; import { domain } from 'mastodon/initial_state';
import Image from 'mastodon/components/image'; import { Image } from 'mastodon/components/image';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
const messages = defineMessages({ const messages = defineMessages({

View file

@ -1,9 +1,9 @@
import React from 'react'; 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 Avatar from './avatar'; import { Avatar } from './avatar';
import AvatarOverlay from './avatar_overlay'; import { AvatarOverlay } from './avatar_overlay';
import RelativeTimestamp from './relative_timestamp'; import { RelativeTimestamp } from './relative_timestamp';
import DisplayName from './display_name'; import DisplayName from './display_name';
import StatusContent from './status_content'; import StatusContent from './status_content';
import StatusActionBar from './status_action_bar'; import StatusActionBar from './status_action_bar';
@ -15,7 +15,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { MediaGallery, Video, Audio } from '../features/ui/util/async-components'; import { MediaGallery, Video, Audio } from '../features/ui/util/async-components';
import { HotKeys } from 'react-hotkeys'; import { HotKeys } from 'react-hotkeys';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { displayMedia } from '../initial_state'; import { displayMedia } from '../initial_state';
import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder'; import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder';

View file

@ -2,7 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import IconButton from './icon_button'; import { IconButton } from './icon_button';
import DropdownMenuContainer from '../containers/dropdown_menu_container'; import DropdownMenuContainer from '../containers/dropdown_menu_container';
import EmojiPickerDropdown from '../features/compose/containers/emoji_picker_dropdown_container'; import EmojiPickerDropdown from '../features/compose/containers/emoji_picker_dropdown_container';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';

View file

@ -6,7 +6,7 @@ import { Link } from 'react-router-dom';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
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';
import { autoPlayGif, languages as preloadedLanguages } from 'mastodon/initial_state'; import { autoPlayGif, languages as preloadedLanguages } from 'mastodon/initial_state';
const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top) const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top)

View file

@ -1,25 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'mastodon/components/icon';
class VerifiedBadge extends React.PureComponent {
static propTypes = {
link: PropTypes.string.isRequired,
verifiedAt: PropTypes.string.isRequired,
};
render () {
const { link } = this.props;
return (
<span className='verified-badge'>
<Icon id='check' className='verified-badge__mark' />
<span dangerouslySetInnerHTML={{ __html: link }} />
</span>
);
}
}
export default VerifiedBadge;

View file

@ -0,0 +1,12 @@
import React from 'react';
import { Icon } from './icon';
type Props = {
link: string;
};
export const VerifiedBadge: React.FC<Props> = ({ link }) => (
<span className='verified-badge'>
<Icon id='check' className='verified-badge__mark' />
<span dangerouslySetInnerHTML={{ __html: link }} />
</span>
);

View file

@ -2,7 +2,7 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { blockDomain, unblockDomain } from '../actions/domain_blocks'; import { blockDomain, unblockDomain } from '../actions/domain_blocks';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import Domain from '../components/domain'; import { Domain } from '../components/domain';
import { openModal } from '../actions/modal'; import { openModal } from '../actions/modal';
const messages = defineMessages({ const messages = defineMessages({

View file

@ -9,9 +9,9 @@ import { Helmet } from 'react-helmet';
import { fetchServer, fetchExtendedDescription, fetchDomainBlocks } from 'mastodon/actions/server'; import { fetchServer, fetchExtendedDescription, fetchDomainBlocks } from 'mastodon/actions/server';
import Account from 'mastodon/containers/account_container'; import Account from 'mastodon/containers/account_container';
import Skeleton from 'mastodon/components/skeleton'; import Skeleton from 'mastodon/components/skeleton';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import classNames from 'classnames'; import classNames from 'classnames';
import Image from 'mastodon/components/image'; import { Image } from 'mastodon/components/image';
const messages = defineMessages({ const messages = defineMessages({
title: { id: 'column.about', defaultMessage: 'About' }, title: { id: 'column.about', defaultMessage: 'About' },

View file

@ -2,7 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
export default class FollowRequestNote extends ImmutablePureComponent { export default class FollowRequestNote extends ImmutablePureComponent {

View file

@ -6,9 +6,9 @@ import Button from 'mastodon/components/button';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { autoPlayGif, me, domain } from 'mastodon/initial_state'; import { autoPlayGif, me, domain } from 'mastodon/initial_state';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import IconButton from 'mastodon/components/icon_button'; import { IconButton } from 'mastodon/components/icon_button';
import Avatar from 'mastodon/components/avatar'; import { Avatar } from 'mastodon/components/avatar';
import { counterRenderer } from 'mastodon/components/common_counter'; import { counterRenderer } from 'mastodon/components/common_counter';
import ShortNumber from 'mastodon/components/short_number'; import ShortNumber from 'mastodon/components/short_number';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';

View file

@ -1,6 +1,6 @@
import Blurhash from 'mastodon/components/blurhash'; import { Blurhash } from 'mastodon/components/blurhash';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { autoPlayGif, displayMedia, useBlurhash } from 'mastodon/initial_state'; import { autoPlayGif, displayMedia, useBlurhash } from 'mastodon/initial_state';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';

View file

@ -2,7 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage } from 'react-intl'; 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 { Link } from 'react-router-dom';

View file

@ -2,12 +2,12 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import { formatTime, getPointerPosition, fileNameFromURL } from 'mastodon/features/video'; import { formatTime, getPointerPosition, fileNameFromURL } from 'mastodon/features/video';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import classNames from 'classnames'; import classNames from 'classnames';
import { throttle, debounce } from 'lodash'; import { throttle, debounce } from 'lodash';
import Visualizer from './visualizer'; import Visualizer from './visualizer';
import { displayMedia, useBlurhash } from '../../initial_state'; import { displayMedia, useBlurhash } from '../../initial_state';
import Blurhash from '../../components/blurhash'; import { Blurhash } from '../../components/blurhash';
import { is } from 'immutable'; import { is } from 'immutable';
const messages = defineMessages({ const messages = defineMessages({

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import Avatar from '../../../components/avatar'; import { Avatar } from '../../../components/avatar';
import DisplayName from '../../../components/display_name'; import DisplayName from '../../../components/display_name';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';

View file

@ -22,7 +22,7 @@ import MarkdownButtonContainer from '../containers/markdown_button_container';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { length } from 'stringz'; import { length } from 'stringz';
import { countableText } from '../util/counter'; import { countableText } from '../util/counter';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import classNames from 'classnames'; import classNames from 'classnames';
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 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';

View file

@ -2,9 +2,9 @@ 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 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 { Link } from 'react-router-dom';
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';

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import IconButton from '../../../components/icon_button'; import { IconButton } from '../../../components/icon_button';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';

View file

@ -3,8 +3,8 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import IconButton from 'mastodon/components/icon_button'; import { IconButton } from 'mastodon/components/icon_button';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import AutosuggestInput from 'mastodon/components/autosuggest_input'; import AutosuggestInput from 'mastodon/components/autosuggest_input';
import classNames from 'classnames'; import classNames from 'classnames';

View file

@ -1,11 +1,11 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { injectIntl, defineMessages } from 'react-intl'; import { injectIntl, defineMessages } from 'react-intl';
import IconButton from '../../../components/icon_button'; import { IconButton } from '../../../components/icon_button';
import Overlay from 'react-overlays/Overlay'; import Overlay from 'react-overlays/Overlay';
import { supportsPassiveEvents } from 'detect-passive-events'; import { supportsPassiveEvents } from 'detect-passive-events';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({ const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },

View file

@ -1,8 +1,8 @@
import React from 'react'; 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 Avatar from '../../../components/avatar'; import { Avatar } from '../../../components/avatar';
import IconButton from '../../../components/icon_button'; import { IconButton } from '../../../components/icon_button';
import DisplayName from '../../../components/display_name'; import DisplayName from '../../../components/display_name';
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';

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { searchEnabled } from 'mastodon/initial_state'; import { searchEnabled } from 'mastodon/initial_state';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import classNames from 'classnames'; import classNames from 'classnames';
import { HASHTAG_REGEX } from 'mastodon/utils/hashtags'; import { HASHTAG_REGEX } from 'mastodon/utils/hashtags';

View file

@ -6,7 +6,7 @@ import AccountContainer from '../../../containers/account_container';
import StatusContainer from '../../../containers/status_container'; import StatusContainer from '../../../containers/status_container';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { ImmutableHashtag as Hashtag } from '../../../components/hashtag'; import { ImmutableHashtag as Hashtag } from '../../../components/hashtag';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { searchEnabled } from '../../../initial_state'; import { searchEnabled } from '../../../initial_state';
import LoadMore from 'mastodon/components/load_more'; import LoadMore from 'mastodon/components/load_more';

View file

@ -5,7 +5,7 @@ import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
export default class Upload extends ImmutablePureComponent { export default class Upload extends ImmutablePureComponent {

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import IconButton from '../../../components/icon_button'; import { IconButton } from '../../../components/icon_button';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';

View file

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Motion from '../../ui/util/optional_motion'; import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
export default class UploadProgress extends React.PureComponent { export default class UploadProgress extends React.PureComponent {

View file

@ -72,6 +72,7 @@ const mapDispatchToProps = (dispatch, { onPickEmoji }) => ({
}, },
onPickEmoji: emoji => { onPickEmoji: emoji => {
// eslint-disable-next-line react-hooks/rules-of-hooks -- this is not a react hook
dispatch(useEmoji(emoji)); dispatch(useEmoji(emoji));
if (onPickEmoji) { if (onPickEmoji) {

View file

@ -26,6 +26,7 @@ const mapDispatchToProps = dispatch => ({
}, },
onClose (value) { onClose (value) {
// eslint-disable-next-line react-hooks/rules-of-hooks -- this is not a react hook
dispatch(useLanguage(value)); dispatch(useLanguage(value));
}, },

View file

@ -14,7 +14,7 @@ import SearchResultsContainer from './containers/search_results_container';
import { openModal } from 'mastodon/actions/modal'; import { openModal } from 'mastodon/actions/modal';
import elephantUIPlane from '../../../images/elephant_ui_plane.svg'; import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
import { mascot } from '../../initial_state'; import { mascot } from '../../initial_state';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { logOut } from 'mastodon/utils/log_out'; import { logOut } from 'mastodon/utils/log_out';
import Column from 'mastodon/components/column'; import Column from 'mastodon/components/column';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';

View file

@ -8,8 +8,8 @@ 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 { Link } from 'react-router-dom';
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';
import { autoPlayGif } from 'mastodon/initial_state'; import { autoPlayGif } from 'mastodon/initial_state';
import classNames from 'classnames'; import classNames from 'classnames';

View file

@ -4,7 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; 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 { Link } from 'react-router-dom';
import Button from 'mastodon/components/button'; import Button from 'mastodon/components/button';

View file

@ -9,7 +9,7 @@ import { addColumn, removeColumn, moveColumn, changeColumnParams } from 'mastodo
import { fetchDirectory, expandDirectory } from 'mastodon/actions/directory'; import { fetchDirectory, expandDirectory } from 'mastodon/actions/directory';
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
import AccountCard from './components/account_card'; import AccountCard from './components/account_card';
import RadioButton from 'mastodon/components/radio_button'; import { RadioButton } from 'mastodon/components/radio_button';
import LoadMore from 'mastodon/components/load_more'; import LoadMore from 'mastodon/components/load_more';
import ScrollContainer from 'mastodon/containers/scroll_container'; import ScrollContainer from 'mastodon/containers/scroll_container';
import LoadingIndicator from 'mastodon/components/loading_indicator'; import LoadingIndicator from 'mastodon/components/loading_indicator';

View file

@ -1,3 +1,5 @@
/* eslint-disable import/no-commonjs --
We need to use CommonJS here due to preval */
// @preval // @preval
// http://www.unicode.org/Public/emoji/5.0/emoji-test.txt // http://www.unicode.org/Public/emoji/5.0/emoji-test.txt
// This file contains the compressed version of the emoji data from // This file contains the compressed version of the emoji data from

View file

@ -1,8 +1,10 @@
// The output of this module is designed to mimic emoji-mart's // The output of this module is designed to mimic emoji-mart's
// "data" object, such that we can use it for a light version of emoji-mart's // "data" object, such that we can use it for a light version of emoji-mart's
// emojiIndex.search functionality. // emojiIndex.search functionality.
const { unicodeToUnifiedName } = require('./unicode_to_unified_name'); import { unicodeToUnifiedName } from './unicode_to_unified_name';
const [ shortCodesToEmojiData, skins, categories, short_names ] = require('./emoji_compressed'); import emojiCompressed from './emoji_compressed';
const [ shortCodesToEmojiData, skins, categories, short_names ] = emojiCompressed;
const emojis = {}; const emojis = {};
@ -33,7 +35,7 @@ Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
}; };
}); });
module.exports = { export {
emojis, emojis,
skins, skins,
categories, categories,

View file

@ -1,7 +1,7 @@
// This code is largely borrowed from: // This code is largely borrowed from:
// https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/emoji-index.js // https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/emoji-index.js
import data from './emoji_mart_data_light'; import * as data from './emoji_mart_data_light';
import { getData, getSanitizedData, uniq, intersect } from './emoji_utils'; import { getData, getSanitizedData, uniq, intersect } from './emoji_utils';
let originalPool = {}; let originalPool = {};

View file

@ -2,14 +2,17 @@
// (i.e. the svg filename) and a shortCode intended to be shown // (i.e. the svg filename) and a shortCode intended to be shown
// as a "title" attribute in an HTML element (aka tooltip). // as a "title" attribute in an HTML element (aka tooltip).
import emojiCompressed from './emoji_compressed';
import { unicodeToFilename } from './unicode_to_filename';
const [ const [
shortCodesToEmojiData, shortCodesToEmojiData,
skins, // eslint-disable-line @typescript-eslint/no-unused-vars _skins,
categories, // eslint-disable-line @typescript-eslint/no-unused-vars _categories,
short_names, // eslint-disable-line @typescript-eslint/no-unused-vars _short_names,
emojisWithoutShortCodes, emojisWithoutShortCodes,
] = require('./emoji_compressed'); ] = emojiCompressed;
const { unicodeToFilename } = require('./unicode_to_filename');
// decompress // decompress
const unicodeMapping = {}; const unicodeMapping = {};
@ -32,4 +35,4 @@ Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
}); });
emojisWithoutShortCodes.forEach(emojiMapData => processEmojiMapData(emojiMapData)); emojisWithoutShortCodes.forEach(emojiMapData => processEmojiMapData(emojiMapData));
module.exports = unicodeMapping; export default unicodeMapping;

View file

@ -1,7 +1,7 @@
// This code is largely borrowed from: // This code is largely borrowed from:
// https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/index.js // https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/index.js
import data from './emoji_mart_data_light'; import * as data from './emoji_mart_data_light';
const buildSearch = (data) => { const buildSearch = (data) => {
const search = []; const search = [];

View file

@ -1,3 +1,6 @@
/* eslint-disable import/no-commonjs --
We need to use CommonJS here as its imported into a preval file (`emoji_compressed.js`) */
// taken from: // taken from:
// https://github.com/twitter/twemoji/blob/47732c7/twemoji-generator.js#L848-L866 // https://github.com/twitter/twemoji/blob/47732c7/twemoji-generator.js#L848-L866
exports.unicodeToFilename = (str) => { exports.unicodeToFilename = (str) => {

View file

@ -1,3 +1,6 @@
/* eslint-disable import/no-commonjs --
We need to use CommonJS here as its imported into a preval file (`emoji_compressed.js`) */
function padLeft(str, num) { function padLeft(str, num) {
while (str.length < num) { while (str.length < num) {
str = '0' + str; str = '0' + str;

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Blurhash from 'mastodon/components/blurhash'; import { Blurhash } from 'mastodon/components/blurhash';
import { accountsCountRenderer } from 'mastodon/components/hashtag'; import { accountsCountRenderer } from 'mastodon/components/hashtag';
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';

View file

@ -5,7 +5,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ColumnHeader from 'mastodon/components/column_header'; import ColumnHeader from 'mastodon/components/column_header';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { fetchFavourites } from 'mastodon/actions/interactions'; import { fetchFavourites } from 'mastodon/actions/interactions';
import LoadingIndicator from 'mastodon/components/loading_indicator'; import LoadingIndicator from 'mastodon/components/loading_indicator';
import ScrollableList from 'mastodon/components/scrollable_list'; import ScrollableList from 'mastodon/components/scrollable_list';

View file

@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { toServerSideType } from 'mastodon/utils/filters'; import { toServerSideType } from 'mastodon/utils/filters';
import { loupeIcon, deleteIcon } from 'mastodon/utils/icons'; import { loupeIcon, deleteIcon } from 'mastodon/utils/icons';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import fuzzysort from 'fuzzysort'; import fuzzysort from 'fuzzysort';
const messages = defineMessages({ const messages = defineMessages({

View file

@ -2,9 +2,9 @@ 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 { Link } from 'react-router-dom';
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';
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';

View file

@ -3,15 +3,15 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import ReactSwipeableViews from 'react-swipeable-views'; import ReactSwipeableViews from 'react-swipeable-views';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import IconButton from 'mastodon/components/icon_button'; import { IconButton } from 'mastodon/components/icon_button';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl';
import { autoPlayGif, reduceMotion, disableSwiping, mascot } from 'mastodon/initial_state'; import { autoPlayGif, reduceMotion, disableSwiping, mascot } from 'mastodon/initial_state';
import elephantUIPlane from 'mastodon/../images/elephant_ui_plane.svg'; import elephantUIPlane from 'mastodon/../images/elephant_ui_plane.svg';
import unicodeMapping from 'mastodon/features/emoji/emoji_unicode_mapping_light'; import unicodeMapping from 'mastodon/features/emoji/emoji_unicode_mapping_light';
import classNames from 'classnames'; import classNames from 'classnames';
import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_picker_dropdown_container'; import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_picker_dropdown_container';
import AnimatedNumber from 'mastodon/components/animated_number'; import { AnimatedNumber } from 'mastodon/components/animated_number';
import TransitionMotion from 'react-motion/lib/TransitionMotion'; import TransitionMotion from 'react-motion/lib/TransitionMotion';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import { assetHost } from 'mastodon/utils/config'; import { assetHost } from 'mastodon/utils/config';

View file

@ -12,7 +12,7 @@ import { injectIntl, FormattedMessage, defineMessages } from 'react-intl';
import { connectHashtagStream } from 'mastodon/actions/streaming'; import { connectHashtagStream } from 'mastodon/actions/streaming';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { fetchHashtag, followHashtag, unfollowHashtag } from 'mastodon/actions/tags'; import { fetchHashtag, followHashtag, unfollowHashtag } from 'mastodon/actions/tags';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import classNames from 'classnames'; import classNames from 'classnames';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';

View file

@ -12,8 +12,8 @@ import { Link } from 'react-router-dom';
import { fetchAnnouncements, toggleShowAnnouncements } from 'mastodon/actions/announcements'; import { fetchAnnouncements, toggleShowAnnouncements } from 'mastodon/actions/announcements';
import AnnouncementsContainer from 'mastodon/features/getting_started/containers/announcements_container'; import AnnouncementsContainer from 'mastodon/features/getting_started/containers/announcements_container';
import classNames from 'classnames'; import classNames from 'classnames';
import IconWithBadge from 'mastodon/components/icon_with_badge'; import { IconWithBadge } from 'mastodon/components/icon_with_badge';
import NotSignedInIndicator from 'mastodon/components/not_signed_in_indicator'; import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
const messages = defineMessages({ const messages = defineMessages({

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { registrationsOpen } from 'mastodon/initial_state'; import { registrationsOpen } from 'mastodon/initial_state';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import classNames from 'classnames'; import classNames from 'classnames';
import { openModal, closeModal } from 'mastodon/actions/modal'; import { openModal, closeModal } from 'mastodon/actions/modal';

View file

@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { makeGetAccount } from '../../../selectors'; import { makeGetAccount } from '../../../selectors';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import Avatar from '../../../components/avatar'; import { Avatar } from '../../../components/avatar';
import DisplayName from '../../../components/display_name'; import DisplayName from '../../../components/display_name';
import { injectIntl } from 'react-intl'; import { injectIntl } from 'react-intl';

View file

@ -3,10 +3,10 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import IconButton from '../../../components/icon_button'; import { IconButton } from '../../../components/icon_button';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { removeFromListAdder, addToListAdder } from '../../../actions/lists'; import { removeFromListAdder, addToListAdder } from '../../../actions/lists';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({ const messages = defineMessages({
remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' }, remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' },

View file

@ -4,9 +4,9 @@ import { connect } from 'react-redux';
import { makeGetAccount } from '../../../selectors'; import { makeGetAccount } from '../../../selectors';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
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';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { removeFromListEditor, addToListEditor } from '../../../actions/lists'; import { removeFromListEditor, addToListEditor } from '../../../actions/lists';

View file

@ -2,7 +2,7 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { changeListEditorTitle, submitListEditor } from '../../../actions/lists'; import { changeListEditorTitle, submitListEditor } from '../../../actions/lists';
import IconButton from '../../../components/icon_button'; import { IconButton } from '../../../components/icon_button';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
const messages = defineMessages({ const messages = defineMessages({

View file

@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { fetchListSuggestions, clearListSuggestions, changeListSuggestions } from '../../../actions/lists'; import { fetchListSuggestions, clearListSuggestions, changeListSuggestions } from '../../../actions/lists';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({ const messages = defineMessages({
search: { id: 'lists.search', defaultMessage: 'Search among people you follow' }, search: { id: 'lists.search', defaultMessage: 'Search among people you follow' },

View file

@ -11,9 +11,9 @@ import { connectListStream } from 'mastodon/actions/streaming';
import { expandListTimeline } from 'mastodon/actions/timelines'; import { expandListTimeline } from 'mastodon/actions/timelines';
import Column from 'mastodon/components/column'; import Column from 'mastodon/components/column';
import ColumnHeader from 'mastodon/components/column_header'; import ColumnHeader from 'mastodon/components/column_header';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import LoadingIndicator from 'mastodon/components/loading_indicator'; import LoadingIndicator from 'mastodon/components/loading_indicator';
import RadioButton from 'mastodon/components/radio_button'; import { RadioButton } from 'mastodon/components/radio_button';
import StatusListContainer from 'mastodon/features/ui/containers/status_list_container'; import StatusListContainer from 'mastodon/features/ui/containers/status_list_container';
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error'; import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
export default class ClearColumnButton extends React.PureComponent { export default class ClearColumnButton extends React.PureComponent {

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const tooltips = defineMessages({ const tooltips = defineMessages({
mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' }, mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' },

View file

@ -1,10 +1,10 @@
import React from 'react'; 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 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 { Link } from 'react-router-dom';
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';

View file

@ -9,7 +9,7 @@ import StatusContainer from 'mastodon/containers/status_container';
import AccountContainer from 'mastodon/containers/account_container'; 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 { Link } from 'react-router-dom';
import classNames from 'classnames'; import classNames from 'classnames';
import EmojiView from '../../../components/emoji_view'; import EmojiView from '../../../components/emoji_view';

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import Icon from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import Button from 'mastodon/components/button'; import Button from 'mastodon/components/button';
import IconButton from 'mastodon/components/icon_button'; import { IconButton } from 'mastodon/components/icon_button';
import { requestBrowserPermission } from 'mastodon/actions/notifications'; import { requestBrowserPermission } from 'mastodon/actions/notifications';
import { changeSetting } from 'mastodon/actions/settings'; import { changeSetting } from 'mastodon/actions/settings';
import { connect } from 'react-redux'; import { connect } from 'react-redux';

Some files were not shown because too many files have changed in this diff Show more