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:
		@@ -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"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user