mirror of https://github.com/Siphonay/mastodon
[Glitch] Include preview cards in status entity in REST API
Port 795f0107d2
to glitch-soc
This commit is contained in:
parent
7f24242ef6
commit
ac9780b844
|
@ -7,6 +7,7 @@ import StatusIcons from './status_icons';
|
||||||
import StatusContent from './status_content';
|
import StatusContent from './status_content';
|
||||||
import StatusActionBar from './status_action_bar';
|
import StatusActionBar from './status_action_bar';
|
||||||
import AttachmentList from './attachment_list';
|
import AttachmentList from './attachment_list';
|
||||||
|
import Card from '../features/status/components/card';
|
||||||
import { injectIntl, FormattedMessage } from 'react-intl';
|
import { injectIntl, FormattedMessage } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { MediaGallery, Video } from 'flavours/glitch/util/async-components';
|
import { MediaGallery, Video } from 'flavours/glitch/util/async-components';
|
||||||
|
@ -477,6 +478,15 @@ export default class Status extends ImmutablePureComponent {
|
||||||
if (!status.get('sensitive') && !(status.get('spoiler_text').length > 0) && settings.getIn(['collapsed', 'backgrounds', 'preview_images'])) {
|
if (!status.get('sensitive') && !(status.get('spoiler_text').length > 0) && settings.getIn(['collapsed', 'backgrounds', 'preview_images'])) {
|
||||||
background = attachments.getIn([0, 'preview_url']);
|
background = attachments.getIn([0, 'preview_url']);
|
||||||
}
|
}
|
||||||
|
} else if (status.get('card')) {
|
||||||
|
media = (
|
||||||
|
<Card
|
||||||
|
onOpenMedia={this.props.onOpenMedia}
|
||||||
|
card={status.get('card')}
|
||||||
|
compact
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
//TODO: set mediaIcon?
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here we prepare extra data-* attributes for CSS selectors.
|
// Here we prepare extra data-* attributes for CSS selectors.
|
||||||
|
|
|
@ -59,10 +59,12 @@ export default class Card extends React.PureComponent {
|
||||||
card: ImmutablePropTypes.map,
|
card: ImmutablePropTypes.map,
|
||||||
maxDescription: PropTypes.number,
|
maxDescription: PropTypes.number,
|
||||||
onOpenMedia: PropTypes.func.isRequired,
|
onOpenMedia: PropTypes.func.isRequired,
|
||||||
|
compact: PropTypes.boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
maxDescription: 50,
|
maxDescription: 50,
|
||||||
|
compact: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
|
@ -131,7 +133,7 @@ export default class Card extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { card, maxDescription } = this.props;
|
const { card, maxDescription, compact } = this.props;
|
||||||
const { width, embedded } = this.state;
|
const { width, embedded } = this.state;
|
||||||
|
|
||||||
if (card === null) {
|
if (card === null) {
|
||||||
|
@ -139,17 +141,17 @@ export default class Card extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
const provider = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name');
|
const provider = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name');
|
||||||
const horizontal = card.get('width') > card.get('height') && (card.get('width') + 100 >= width) || card.get('type') !== 'link';
|
const horizontal = (!compact && card.get('width') > card.get('height') && (card.get('width') + 100 >= width)) || card.get('type') !== 'link' || embedded;
|
||||||
const className = classnames('status-card', { horizontal });
|
|
||||||
const interactive = card.get('type') !== 'link';
|
const interactive = card.get('type') !== 'link';
|
||||||
|
const className = classnames('status-card', { horizontal, compact, interactive });
|
||||||
const title = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
|
const title = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
|
||||||
const ratio = card.get('width') / card.get('height');
|
const ratio = compact ? 16 / 9 : card.get('width') / card.get('height');
|
||||||
const height = card.get('width') > card.get('height') ? (width / ratio) : (width * ratio);
|
const height = card.get('width') > card.get('height') ? (width / ratio) : (width * ratio);
|
||||||
|
|
||||||
const description = (
|
const description = (
|
||||||
<div className='status-card__content'>
|
<div className='status-card__content'>
|
||||||
{title}
|
{title}
|
||||||
{!horizontal && <p className='status-card__description'>{trim(card.get('description') || '', maxDescription)}</p>}
|
{!(horizontal || compact) && <p className='status-card__description'>{trim(card.get('description') || '', maxDescription)}</p>}
|
||||||
<span className='status-card__host'>{provider}</span>
|
<span className='status-card__host'>{provider}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -174,7 +176,7 @@ export default class Card extends React.PureComponent {
|
||||||
<div className='status-card__actions'>
|
<div className='status-card__actions'>
|
||||||
<div>
|
<div>
|
||||||
<button onClick={this.handleEmbedClick}><i className={`fa fa-${iconVariant}`} /></button>
|
<button onClick={this.handleEmbedClick}><i className={`fa fa-${iconVariant}`} /></button>
|
||||||
<a href={card.get('url')} target='_blank' rel='noopener'><i className='fa fa-external-link' /></a>
|
{horizontal && <a href={card.get('url')} target='_blank' rel='noopener'><i className='fa fa-external-link' /></a>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -184,7 +186,7 @@ export default class Card extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<div className={className} ref={this.setRef}>
|
<div className={className} ref={this.setRef}>
|
||||||
{embed}
|
{embed}
|
||||||
{description}
|
{!compact && description}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (card.get('image')) {
|
} else if (card.get('image')) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { connect } from 'react-redux';
|
||||||
import Card from '../components/card';
|
import Card from '../components/card';
|
||||||
|
|
||||||
const mapStateToProps = (state, { statusId }) => ({
|
const mapStateToProps = (state, { statusId }) => ({
|
||||||
card: state.getIn(['cards', statusId], null),
|
card: state.getIn(['statuses', statusId, 'card'], null),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(Card);
|
export default connect(mapStateToProps)(Card);
|
||||||
|
|
|
@ -15,7 +15,6 @@ import settings from './settings';
|
||||||
import local_settings from './local_settings';
|
import local_settings from './local_settings';
|
||||||
import push_notifications from './push_notifications';
|
import push_notifications from './push_notifications';
|
||||||
import status_lists from './status_lists';
|
import status_lists from './status_lists';
|
||||||
import cards from './cards';
|
|
||||||
import mutes from './mutes';
|
import mutes from './mutes';
|
||||||
import reports from './reports';
|
import reports from './reports';
|
||||||
import contexts from './contexts';
|
import contexts from './contexts';
|
||||||
|
@ -47,7 +46,6 @@ const reducers = {
|
||||||
settings,
|
settings,
|
||||||
local_settings,
|
local_settings,
|
||||||
push_notifications,
|
push_notifications,
|
||||||
cards,
|
|
||||||
mutes,
|
mutes,
|
||||||
reports,
|
reports,
|
||||||
contexts,
|
contexts,
|
||||||
|
|
|
@ -23,6 +23,9 @@ import {
|
||||||
STATUS_MUTE_SUCCESS,
|
STATUS_MUTE_SUCCESS,
|
||||||
STATUS_UNMUTE_SUCCESS,
|
STATUS_UNMUTE_SUCCESS,
|
||||||
} from 'flavours/glitch/actions/statuses';
|
} from 'flavours/glitch/actions/statuses';
|
||||||
|
import {
|
||||||
|
STATUS_CARD_FETCH_SUCCESS
|
||||||
|
} from 'flavours/glitch/actions/cards';
|
||||||
import {
|
import {
|
||||||
TIMELINE_UPDATE,
|
TIMELINE_UPDATE,
|
||||||
TIMELINE_DELETE,
|
TIMELINE_DELETE,
|
||||||
|
@ -143,6 +146,8 @@ export default function statuses(state = initialState, action) {
|
||||||
return normalizeStatuses(state, action.statuses);
|
return normalizeStatuses(state, action.statuses);
|
||||||
case TIMELINE_DELETE:
|
case TIMELINE_DELETE:
|
||||||
return deleteStatus(state, action.id, action.references);
|
return deleteStatus(state, action.id, action.references);
|
||||||
|
case STATUS_CARD_FETCH_SUCCESS:
|
||||||
|
return state.setIn([action.id, 'card'], fromJS(action.card));
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -731,6 +731,9 @@ a.status-card {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-card__image {
|
.status-card__image {
|
||||||
|
@ -755,6 +758,31 @@ a.status-card {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-card.compact {
|
||||||
|
border-color: lighten($ui-base-color, 4%);
|
||||||
|
|
||||||
|
&.interactive {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-card__content {
|
||||||
|
padding: 8px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-card__title {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-card__image {
|
||||||
|
flex: 0 0 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.status-card.compact:hover {
|
||||||
|
background-color: lighten($ui-base-color, 4%);
|
||||||
|
}
|
||||||
|
|
||||||
.status-card__image-image {
|
.status-card__image-image {
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
Loading…
Reference in New Issue