Merge pull request #2236 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to e387175fc9
th-downstream
commit
0222df6047
@ -1,8 +1,9 @@
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
|
||||
import type { LayoutType } from '../is_mobile';
|
||||
|
||||
type ChangeLayoutPayload = {
|
||||
interface ChangeLayoutPayload {
|
||||
layout: LayoutType;
|
||||
};
|
||||
}
|
||||
export const changeLayout =
|
||||
createAction<ChangeLayoutPayload>('APP_LAYOUT_CHANGE');
|
||||
|
@ -1,83 +0,0 @@
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { autoPlayGif } from 'flavours/glitch/initial_state';
|
||||
import Skeleton from 'flavours/glitch/components/skeleton';
|
||||
|
||||
export default class DisplayName extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
account: ImmutablePropTypes.map,
|
||||
others: ImmutablePropTypes.list,
|
||||
localDomain: PropTypes.string,
|
||||
inline: PropTypes.bool,
|
||||
};
|
||||
|
||||
handleMouseEnter = ({ currentTarget }) => {
|
||||
if (autoPlayGif) {
|
||||
return;
|
||||
}
|
||||
|
||||
const emojis = currentTarget.querySelectorAll('.custom-emoji');
|
||||
|
||||
for (var i = 0; i < emojis.length; i++) {
|
||||
let emoji = emojis[i];
|
||||
emoji.src = emoji.getAttribute('data-original');
|
||||
}
|
||||
};
|
||||
|
||||
handleMouseLeave = ({ currentTarget }) => {
|
||||
if (autoPlayGif) {
|
||||
return;
|
||||
}
|
||||
|
||||
const emojis = currentTarget.querySelectorAll('.custom-emoji');
|
||||
|
||||
for (var i = 0; i < emojis.length; i++) {
|
||||
let emoji = emojis[i];
|
||||
emoji.src = emoji.getAttribute('data-static');
|
||||
}
|
||||
};
|
||||
|
||||
render () {
|
||||
const { others, localDomain, inline } = this.props;
|
||||
|
||||
let displayName, suffix, account;
|
||||
|
||||
if (others && others.size > 1) {
|
||||
displayName = others.take(2).map(a => <bdi key={a.get('id')}><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi>).reduce((prev, cur) => [prev, ', ', cur]);
|
||||
|
||||
if (others.size - 2 > 0) {
|
||||
suffix = `+${others.size - 2}`;
|
||||
}
|
||||
} else if ((others && others.size > 0) || this.props.account) {
|
||||
if (others && others.size > 0) {
|
||||
account = others.first();
|
||||
} else {
|
||||
account = this.props.account;
|
||||
}
|
||||
|
||||
let acct = account.get('acct');
|
||||
|
||||
if (acct.indexOf('@') === -1 && localDomain) {
|
||||
acct = `${acct}@${localDomain}`;
|
||||
}
|
||||
|
||||
displayName = <bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi>;
|
||||
suffix = <span className='display-name__account'>@{acct}</span>;
|
||||
} else {
|
||||
displayName = <bdi><strong className='display-name__html'><Skeleton width='10ch' /></strong></bdi>;
|
||||
suffix = <span className='display-name__account'><Skeleton width='7ch' /></span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={classNames('display-name', { inline })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
|
||||
{displayName}
|
||||
{inline ? ' ' : null}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
import React from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import type { List } from 'immutable';
|
||||
|
||||
import type { Account } from 'flavours/glitch/types/resources';
|
||||
|
||||
import { autoPlayGif } from '../initial_state';
|
||||
|
||||
import { Skeleton } from './skeleton';
|
||||
|
||||
interface Props {
|
||||
account: Account;
|
||||
others: List<Account>;
|
||||
localDomain: string;
|
||||
inline?: boolean;
|
||||
}
|
||||
export class DisplayName extends React.PureComponent<Props> {
|
||||
handleMouseEnter: React.ReactEventHandler<HTMLSpanElement> = ({
|
||||
currentTarget,
|
||||
}) => {
|
||||
if (autoPlayGif) {
|
||||
return;
|
||||
}
|
||||
|
||||
const emojis =
|
||||
currentTarget.querySelectorAll<HTMLImageElement>('img.custom-emoji');
|
||||
|
||||
emojis.forEach((emoji) => {
|
||||
const originalSrc = emoji.getAttribute('data-original');
|
||||
if (originalSrc != null) emoji.src = originalSrc;
|
||||
});
|
||||
};
|
||||
|
||||
handleMouseLeave: React.ReactEventHandler<HTMLSpanElement> = ({
|
||||
currentTarget,
|
||||
}) => {
|
||||
if (autoPlayGif) {
|
||||
return;
|
||||
}
|
||||
|
||||
const emojis =
|
||||
currentTarget.querySelectorAll<HTMLImageElement>('img.custom-emoji');
|
||||
|
||||
emojis.forEach((emoji) => {
|
||||
const staticSrc = emoji.getAttribute('data-static');
|
||||
if (staticSrc != null) emoji.src = staticSrc;
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { others, localDomain, inline } = this.props;
|
||||
|
||||
let displayName: React.ReactNode, suffix: React.ReactNode, account: Account;
|
||||
|
||||
if (others && others.size > 1) {
|
||||
displayName = others
|
||||
.take(2)
|
||||
.map((a) => (
|
||||
<bdi key={a.get('id')}>
|
||||
<strong
|
||||
className='display-name__html'
|
||||
dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }}
|
||||
/>
|
||||
</bdi>
|
||||
))
|
||||
.reduce((prev, cur) => [prev, ', ', cur]);
|
||||
|
||||
if (others.size - 2 > 0) {
|
||||
suffix = `+${others.size - 2}`;
|
||||
}
|
||||
} else if ((others && others.size > 0) || this.props.account) {
|
||||
if (others && others.size > 0) {
|
||||
account = others.first();
|
||||
} else {
|
||||
account = this.props.account;
|
||||
}
|
||||
|
||||
let acct = account.get('acct');
|
||||
|
||||
if (acct.indexOf('@') === -1 && localDomain) {
|
||||
acct = `${acct}@${localDomain}`;
|
||||
}
|
||||
|
||||
displayName = (
|
||||
<bdi>
|
||||
<strong
|
||||
className='display-name__html'
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: account.get('display_name_html'),
|
||||
}}
|
||||
/>
|
||||
</bdi>
|
||||
);
|
||||
suffix = <span className='display-name__account'>@{acct}</span>;
|
||||
} else {
|
||||
displayName = (
|
||||
<bdi>
|
||||
<strong className='display-name__html'>
|
||||
<Skeleton width='10ch' />
|
||||
</strong>
|
||||
</bdi>
|
||||
);
|
||||
suffix = (
|
||||
<span className='display-name__account'>
|
||||
<Skeleton width='7ch' />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
className={classNames('display-name', { inline })}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
>
|
||||
{displayName}
|
||||
{inline ? ' ' : null}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,15 +1,17 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { Blurhash } from './blurhash';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
type Props = {
|
||||
import { Blurhash } from './blurhash';
|
||||
|
||||
interface Props {
|
||||
src: string;
|
||||
srcSet?: string;
|
||||
blurhash?: string;
|
||||
className?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const Image: React.FC<Props> = ({
|
||||
export const ServerHeroImage: React.FC<Props> = ({
|
||||
src,
|
||||
srcSet,
|
||||
blurhash,
|
@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Skeleton = ({ width, height }) => <span className='skeleton' style={{ width, height }}>‌</span>;
|
||||
|
||||
Skeleton.propTypes = {
|
||||
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
};
|
||||
|
||||
export default Skeleton;
|
@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
interface Props {
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
}
|
||||
|
||||
export const Skeleton: React.FC<Props> = ({ width, height }) => (
|
||||
<span className='skeleton' style={{ width, height }}>
|
||||
‌
|
||||
</span>
|
||||
);
|
@ -1,18 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
const TimelineHint = ({ resource, url }) => (
|
||||
<div className='timeline-hint'>
|
||||
<strong><FormattedMessage id='timeline_hint.remote_resource_not_displayed' defaultMessage='{resource} from other servers are not displayed.' values={{ resource }} /></strong>
|
||||
<br />
|
||||
<a href={url} target='_blank'><FormattedMessage id='account.browse_more_on_origin_server' defaultMessage='Browse more on the original profile' /></a>
|
||||
</div>
|
||||
);
|
||||
|
||||
TimelineHint.propTypes = {
|
||||
resource: PropTypes.node.isRequired,
|
||||
url: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default TimelineHint;
|
@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
interface Props {
|
||||
resource: JSX.Element;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export const TimelineHint: React.FC<Props> = ({ resource, url }) => (
|
||||
<div className='timeline-hint'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='timeline_hint.remote_resource_not_displayed'
|
||||
defaultMessage='{resource} from other servers are not displayed.'
|
||||
values={{ resource }}
|
||||
/>
|
||||
</strong>
|
||||
<br />
|
||||
<a href={url} target='_blank' rel='noopener noreferrer'>
|
||||
<FormattedMessage
|
||||
id='account.browse_more_on_origin_server'
|
||||
defaultMessage='Browse more on the original profile'
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue