mirror of
https://git.kescher.at/CatCatNya/catstodon.git
synced 2024-11-22 10:38:07 +01:00
Merge commit '89269e4b713e3291a5c8c29b8d2e7b950b60eb35' into glitch-soc/merge-upstream
Conflicts: - `tsconfig.json`: Upstream changed the config to properly process imports. Glitch-soc had previously already done so. Changed the config to better match upstream.
This commit is contained in:
commit
8b568755ad
17 changed files with 163 additions and 149 deletions
|
@ -1,10 +1,11 @@
|
|||
import { createAction } from '@reduxjs/toolkit';
|
||||
import type { LayoutType } from '../is_mobile';
|
||||
|
||||
export const focusApp = createAction('APP_FOCUS');
|
||||
export const unfocusApp = createAction('APP_UNFOCUS');
|
||||
|
||||
type ChangeLayoutPayload = {
|
||||
layout: 'mobile' | 'single-column' | 'multi-column';
|
||||
layout: LayoutType;
|
||||
};
|
||||
export const changeLayout =
|
||||
createAction<ChangeLayoutPayload>('APP_LAYOUT_CHANGE');
|
||||
|
|
|
@ -151,7 +151,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 (
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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>
|
|
@ -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);
|
42
app/javascript/mastodon/components/domain.tsx
Normal file
42
app/javascript/mastodon/components/domain.tsx
Normal 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);
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
27
app/javascript/mastodon/components/image.tsx
Normal file
27
app/javascript/mastodon/components/image.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
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>
|
||||
);
|
||||
};
|
||||
|
||||
export default Image;
|
|
@ -1,7 +1,7 @@
|
|||
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.' />
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
30
app/javascript/mastodon/components/radio_button.tsx
Normal file
30
app/javascript/mastodon/components/radio_button.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
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>
|
||||
);
|
||||
};
|
||||
|
||||
export default RadioButton;
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
14
app/javascript/mastodon/components/verified_badge.tsx
Normal file
14
app/javascript/mastodon/components/verified_badge.tsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
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>
|
||||
);
|
||||
|
||||
export default VerifiedBadge;
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { blockDomain, unblockDomain } from '../actions/domain_blocks';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import Domain from '../components/domain';
|
||||
import { Domain } from '../components/domain';
|
||||
import { openModal } from '../actions/modal';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
|
34
app/javascript/types/image.d.ts
vendored
Normal file
34
app/javascript/types/image.d.ts
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
declare module '*.avif' {
|
||||
const path: string;
|
||||
export default path;
|
||||
}
|
||||
|
||||
declare module '*.gif' {
|
||||
const path: string;
|
||||
export default path;
|
||||
}
|
||||
|
||||
declare module '*.jpg' {
|
||||
const path: string;
|
||||
export default path;
|
||||
}
|
||||
|
||||
declare module '*.jpg' {
|
||||
const path: string;
|
||||
export default path;
|
||||
}
|
||||
|
||||
declare module '*.png' {
|
||||
const path: string;
|
||||
export default path;
|
||||
}
|
||||
|
||||
declare module '*.svg' {
|
||||
const path: string;
|
||||
export default path;
|
||||
}
|
||||
|
||||
declare module '*.webp' {
|
||||
const path: string;
|
||||
export default path;
|
||||
}
|
|
@ -8,14 +8,17 @@
|
|||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"*": ["app/javascript/*"]
|
||||
"*": ["app/javascript/*"],
|
||||
"mastodon": ["app/javascript/mastodon"],
|
||||
"mastodon/*": ["app/javascript/mastodon/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"app/javascript/mastodon",
|
||||
"app/javascript/flavours/glitch",
|
||||
"app/javascript/packs"
|
||||
"app/javascript/packs",
|
||||
"app/javascript/types",
|
||||
"app/javascript/flavours/glitch"
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue