Status: display a placeholder Card on own links, poll for updated card

features-override
Alex Gleason 2021-11-15 19:08:27 -06:00
rodzic 3414363245
commit 1714ac03d2
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
6 zmienionych plików z 89 dodań i 2 usunięć

Wyświetl plik

@ -3,6 +3,7 @@ import { deleteFromTimelines } from './timelines';
import { importFetchedStatus, importFetchedStatuses } from './importer';
import { openModal } from './modal';
import { isLoggedIn } from 'soapbox/utils/auth';
import { shouldHaveCard } from 'soapbox/utils/status';
export const STATUS_CREATE_REQUEST = 'STATUS_CREATE_REQUEST';
export const STATUS_CREATE_SUCCESS = 'STATUS_CREATE_SUCCESS';
@ -44,8 +45,31 @@ export function createStatus(params, idempotencyKey) {
return api(getState).post('/api/v1/statuses', params, {
headers: { 'Idempotency-Key': idempotencyKey },
}).then(({ data: status }) => {
// The backend might still be processing the rich media attachment
if (!status.card && shouldHaveCard(status)) {
status.expectsCard = true;
}
dispatch(importFetchedStatus(status, idempotencyKey));
dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey });
// Poll the backend for the updated card
if (status.expectsCard) {
const delay = 1000;
const poll = (retries = 5) => {
api(getState).get(`/api/v1/statuses/${status.id}`).then(response => {
if (response.data && response.data.card) {
dispatch(importFetchedStatus(response.data));
} else if (retries > 0 && response.status === 200) {
setTimeout(() => poll(retries - 1), delay);
}
}).catch(console.error);
};
setTimeout(() => poll(), delay);
}
return status;
}).catch(error => {
dispatch({ type: STATUS_CREATE_FAIL, error, params, idempotencyKey });

Wyświetl plik

@ -19,6 +19,7 @@ import Icon from 'soapbox/components/icon';
import { Link, NavLink } from 'react-router-dom';
import { getDomain } from 'soapbox/utils/accounts';
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
import PlaceholderCard from 'soapbox/features/placeholder/components/placeholder_card';
// We use the component (and not the container) since we do not want
// to use the progress bar to show download progress
@ -465,6 +466,10 @@ class Status extends ImmutablePureComponent {
defaultWidth={this.props.cachedMediaWidth}
/>
);
} else if (status.get('expectsCard', false)) {
media = (
<PlaceholderCard />
);
}
if (otherAccounts && otherAccounts.size > 1) {

Wyświetl plik

@ -0,0 +1,29 @@
import React from 'react';
import { randomIntFromInterval, generateText } from '../utils';
export default class PlaceholderCard extends React.Component {
shouldComponentUpdate() {
// Re-rendering this will just cause the random lengths to jump around.
// There's basically no reason to ever do it.
return false;
}
render() {
return (
<div className='status-card status-card--placeholder'>
<div className='status-card__image' />
<div className='status-card__content'>
<span className='status-card__title'>{generateText(randomIntFromInterval(5, 25))}</span>
<p className='status-card__description'>
{generateText(randomIntFromInterval(5, 75))}
</p>
<span className='status-card__host'>
{generateText(randomIntFromInterval(5, 15))}
</span>
</div>
</div>
);
}
}

Wyświetl plik

@ -171,7 +171,7 @@ export default class Card extends React.PureComponent {
const description = (
<div className='status-card__content'>
{title}
<span className='status-card__title'>{title}</span>
<p className='status-card__description'>{trim(card.get('description') || '', maxDescription)}</p>
<span className='status-card__host'><Icon src={require('@tabler/icons/icons/link.svg')} /> {provider}</span>
</div>

Wyświetl plik

@ -0,0 +1,15 @@
export const getFirstExternalLink = status => {
try {
// Pulled from Pleroma's media parser
const selector = 'a:not(.mention,.hashtag,.attachment,[rel~="tag"])';
const element = document.createElement('div');
element.innerHTML = status.content;
return element.querySelector(selector);
} catch {
return null;
}
};
export const shouldHaveCard = status => {
return Boolean(getFirstExternalLink(status));
};

Wyświetl plik

@ -1,6 +1,7 @@
.placeholder-status,
.placeholder-hashtag,
.notification--placeholder {
.notification--placeholder,
.status-card--placeholder {
position: relative;
&::before {
@ -105,3 +106,16 @@
background: transparent;
box-shadow: none;
}
.status-card--placeholder {
pointer-events: none;
.status-card__title,
.status-card__description,
.status-card__host {
letter-spacing: -1px;
color: var(--brand-color) !important;
word-break: break-all;
opacity: 0.1;
}
}