next See merge request soapbox-pub/soapbox-fe!1176next-virtuoso-proof
commit
9d996b355d
@ -1,59 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
import Icon from 'soapbox/components/icon';
|
|
||||||
|
|
||||||
const filename = url => url.split('/').pop().split('#')[0].split('?')[0];
|
|
||||||
|
|
||||||
export default class AttachmentList extends ImmutablePureComponent {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
media: ImmutablePropTypes.list.isRequired,
|
|
||||||
compact: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { media, compact } = this.props;
|
|
||||||
|
|
||||||
if (compact) {
|
|
||||||
return (
|
|
||||||
<div className='attachment-list compact'>
|
|
||||||
<ul className='attachment-list__list'>
|
|
||||||
{media.map(attachment => {
|
|
||||||
const displayUrl = attachment.get('remote_url') || attachment.get('url');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li key={attachment.get('id')}>
|
|
||||||
<a href={displayUrl} target='_blank' rel='noopener'><Icon id='link' /> {filename(displayUrl)}</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='attachment-list'>
|
|
||||||
<div className='attachment-list__icon'>
|
|
||||||
<Icon id='link' />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul className='attachment-list__list'>
|
|
||||||
{media.map(attachment => {
|
|
||||||
const displayUrl = attachment.get('remote_url') || attachment.get('url');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li key={attachment.get('id')}>
|
|
||||||
<a href={displayUrl} target='_blank' rel='noopener'>{filename(displayUrl)}</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import Icon from 'soapbox/components/icon';
|
||||||
|
|
||||||
|
import type { Attachment as AttachmentEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
|
const filename = (url: string) => url.split('/').pop()!.split('#')[0].split('?')[0];
|
||||||
|
|
||||||
|
interface IAttachmentList {
|
||||||
|
media: AttachmentEntity[],
|
||||||
|
compact?: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttachmentList: React.FC<IAttachmentList> = ({ media, compact }) => {
|
||||||
|
if (compact) {
|
||||||
|
return (
|
||||||
|
<div className='attachment-list compact'>
|
||||||
|
<ul className='attachment-list__list'>
|
||||||
|
{media.map(attachment => {
|
||||||
|
const displayUrl = attachment.get('remote_url') || attachment.get('url');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li key={attachment.get('id')}>
|
||||||
|
<a href={displayUrl} target='_blank' rel='noopener'><Icon id='link' /> {filename(displayUrl)}</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='attachment-list'>
|
||||||
|
<div className='attachment-list__icon'>
|
||||||
|
<Icon id='link' />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul className='attachment-list__list'>
|
||||||
|
{media.map(attachment => {
|
||||||
|
const displayUrl = attachment.get('remote_url') || attachment.get('url');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li key={attachment.get('id')}>
|
||||||
|
<a href={displayUrl} target='_blank' rel='noopener'>{filename(displayUrl)}</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AttachmentList;
|
@ -1,52 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import { injectIntl, FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
import { Button } from '../../../components/ui';
|
|
||||||
|
|
||||||
export default @injectIntl
|
|
||||||
class MissingDescriptionModal extends React.PureComponent {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
onClose: PropTypes.func,
|
|
||||||
onContinue: PropTypes.func.isRequired,
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.button.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleContinue = () => {
|
|
||||||
this.props.onClose();
|
|
||||||
this.props.onContinue();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCancel = () => {
|
|
||||||
this.props.onClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
setRef = (c) => {
|
|
||||||
this.button = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className='modal-root__modal confirmation-modal'>
|
|
||||||
<div className='confirmation-modal__container'>
|
|
||||||
<FormattedMessage id='missing_description_modal.text' defaultMessage='You have not entered a description for all attachments. Continue anyway?' />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='confirmation-modal__action-bar'>
|
|
||||||
<Button onClick={this.handleCancel} className='confirmation-modal__cancel-button' ref={this.setRef}>
|
|
||||||
<FormattedMessage id='missing_description_modal.cancel' defaultMessage='Cancel' />
|
|
||||||
</Button>
|
|
||||||
<Button onClick={this.handleContinue}>
|
|
||||||
<FormattedMessage id='missing_description_modal.continue' defaultMessage='Post' />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { injectIntl, FormattedMessage, IntlShape, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
import { Modal } from 'soapbox/components/ui';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
modalTitle: { id: 'missing_description_modal.text', defaultMessage: 'You have not entered a description for all attachments.' },
|
||||||
|
post: { id: 'missing_description_modal.continue', defaultMessage: 'Post' },
|
||||||
|
cancel: { id: 'missing_description_modal.cancel', defaultMessage: 'Cancel' },
|
||||||
|
});
|
||||||
|
|
||||||
|
interface IMissingDescriptionModal {
|
||||||
|
onClose: () => void,
|
||||||
|
onContinue: () => void,
|
||||||
|
intl: IntlShape,
|
||||||
|
}
|
||||||
|
|
||||||
|
const MissingDescriptionModal: React.FC<IMissingDescriptionModal> = ({ onClose, onContinue, intl }) => {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title={intl.formatMessage(messages.modalTitle)}
|
||||||
|
confirmationAction={onContinue}
|
||||||
|
confirmationText={intl.formatMessage(messages.post)}
|
||||||
|
confirmationTheme='danger'
|
||||||
|
cancelText={intl.formatMessage(messages.cancel)}
|
||||||
|
cancelAction={onClose}
|
||||||
|
>
|
||||||
|
<p className='text-gray-600 dark:text-gray-300'>
|
||||||
|
<FormattedMessage id='missing_description_modal.description' defaultMessage='Continue anyway?' />
|
||||||
|
</p>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(MissingDescriptionModal);
|
Loading…
Reference in new issue