1
0
Fork 0
forked from gitea/nas

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

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

View file

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

View file

@ -1,19 +1,19 @@
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Avatar from './avatar';
import { Avatar } from './avatar';
import DisplayName from './display_name';
import IconButton from './icon_button';
import { IconButton } from './icon_button';
import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { me } from '../initial_state';
import RelativeTimestamp from './relative_timestamp';
import { RelativeTimestamp } from './relative_timestamp';
import Skeleton from 'mastodon/components/skeleton';
import { Link } from 'react-router-dom';
import { counterRenderer } from 'mastodon/components/common_counter';
import ShortNumber from 'mastodon/components/short_number';
import classNames from 'classnames';
import VerifiedBadge from 'mastodon/components/verified_badge';
import { VerifiedBadge } from 'mastodon/components/verified_badge';
const messages = defineMessages({
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'));
if (firstVerifiedField) {
verification = <>· <VerifiedBadge link={firstVerifiedField.get('value')} verifiedAt={firstVerifiedField.get('verified_at')} /></>;
verification = <>· <VerifiedBadge link={firstVerifiedField.get('value')} /></>;
}
return (

View file

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

View file

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage } from 'react-intl';
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];

View file

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

View file

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { autoPlayGif } from '../initial_state';
import Avatar from './avatar';
import { Avatar } from './avatar';
export default class AvatarComposite extends React.PureComponent {

View file

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

View file

@ -9,13 +9,13 @@ type Props = {
children?: never;
[key: string]: any;
}
function Blurhash({
const Blurhash: React.FC<Props> = ({
hash,
width = 32,
height = width,
dummy = false,
...canvasProps
}: Props) {
}) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
@ -40,6 +40,8 @@ function Blurhash({
return (
<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';
const Check = () => (
export const Check: React.FC = () => (
<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' />
</svg>
);
export default Check;

View file

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

View file

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

View file

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

View file

@ -1,5 +1,5 @@
import React from 'react';
import IconButton from './icon_button';
import { IconButton } from './icon_button';
import PropTypes from 'prop-types';
import { injectIntl, defineMessages } from 'react-intl';
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 PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import IconButton from './icon_button';
import { IconButton } from './icon_button';
import Overlay from 'react-overlays/Overlay';
import { supportsPassiveEvents } from 'detect-passive-events';
import classNames from 'classnames';

View file

@ -1,11 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
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 { connect } from 'react-redux';
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';
const mapDispatchToProps = (dispatch, { statusId }) => ({

View file

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

View file

@ -5,9 +5,7 @@ import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { Link } from 'react-router-dom';
// @ts-expect-error
import ShortNumber from 'mastodon/components/short_number';
// @ts-expect-error
import Skeleton from 'mastodon/components/skeleton';
import classNames from 'classnames';

View file

@ -10,5 +10,3 @@ type Props = {
}
export const Icon: React.FC<Props> = ({ id, className, 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,
deactivate: boolean,
}
export default class IconButton extends React.PureComponent<Props, States> {
export class IconButton extends React.PureComponent<Props, States> {
static defaultProps = {
size: 18,

View file

@ -9,12 +9,10 @@ type Props = {
issueBadge: boolean;
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'>
<Icon id={id} fixedWidth className={className} />
{count > 0 && <i className='icon-with-badge__badge'>{formatNumber(count)}</i>}
{issueBadge && <i className='icon-with-badge__issue-badge' />}
</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 { connect } from 'react-redux';
import { makeGetAccount } from 'mastodon/selectors';
import Avatar from 'mastodon/components/avatar';
import { Avatar } from 'mastodon/components/avatar';
const makeMapStateToProps = () => {
const getAccount = makeGetAccount();

View file

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, defineMessages } from 'react-intl';
import Icon from 'mastodon/components/icon';
import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({
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 PropTypes from 'prop-types';
import { is } from 'immutable';
import IconButton from './icon_button';
import { IconButton } from './icon_button';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { autoPlayGif, cropImages, displayMedia, displayMediaExpand, useBlurhash } from '../initial_state';
import { debounce } from 'lodash';
import Blurhash from 'mastodon/components/blurhash';
import { Blurhash } from 'mastodon/components/blurhash';
const messages = defineMessages({
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 { FormattedMessage } from 'react-intl';
const NotSignedInIndicator = () => (
export const NotSignedInIndicator: React.FC = () => (
<div className='scrollable scrollable--flex'>
<div className='empty-column-indicator'>
<FormattedMessage id='not_signed_in_indicator.not_signed_in' defaultMessage='You need to sign in to access this resource.' />
</div>
</div>
);
export default NotSignedInIndicator;

View file

@ -1,6 +1,6 @@
import React from 'react';
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 { connect } from 'react-redux';
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 escapeTextContentForBrowser from 'escape-html';
import emojify from 'mastodon/features/emoji/emoji';
import RelativeTimestamp from './relative_timestamp';
import Icon from 'mastodon/components/icon';
import { RelativeTimestamp } from './relative_timestamp';
import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({
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 { List as ImmutableList } from 'immutable';
import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../features/ui/util/fullscreen';
import LoadingIndicator from './loading_indicator';
import { connect } from 'react-redux';
@ -236,10 +237,10 @@ class ScrollableList extends PureComponent {
attachScrollListener () {
if (this.props.bindToDocument) {
document.addEventListener('scroll', this.handleScroll);
document.addEventListener('wheel', this.handleWheel);
document.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : undefined);
} else {
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 Account from 'mastodon/containers/account_container';
import { domain } from 'mastodon/initial_state';
import Image from 'mastodon/components/image';
import { Image } from 'mastodon/components/image';
import { Link } from 'react-router-dom';
const messages = defineMessages({

View file

@ -1,9 +1,9 @@
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Avatar from './avatar';
import AvatarOverlay from './avatar_overlay';
import RelativeTimestamp from './relative_timestamp';
import { Avatar } from './avatar';
import { AvatarOverlay } from './avatar_overlay';
import { RelativeTimestamp } from './relative_timestamp';
import DisplayName from './display_name';
import StatusContent from './status_content';
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 { HotKeys } from 'react-hotkeys';
import classNames from 'classnames';
import Icon from 'mastodon/components/icon';
import { Icon } from 'mastodon/components/icon';
import { displayMedia } from '../initial_state';
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 { connect } from 'react-redux';
import PropTypes from 'prop-types';
import IconButton from './icon_button';
import { IconButton } from './icon_button';
import DropdownMenuContainer from '../containers/dropdown_menu_container';
import EmojiPickerDropdown from '../features/compose/containers/emoji_picker_dropdown_container';
import { defineMessages, injectIntl } from 'react-intl';

View file

@ -6,7 +6,7 @@ import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import classnames from 'classnames';
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';
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>
);