attachments frontend
Этот коммит содержится в:
@@ -109,6 +109,7 @@ export default class CreateComment extends React.Component {
|
||||
post.pending_post_id = `${userId}:${time}`;
|
||||
post.user_id = userId;
|
||||
post.create_at = time;
|
||||
post.attachments = [];
|
||||
|
||||
PostStore.storePendingPost(post);
|
||||
PostStore.storeCommentDraft(this.props.rootId, null);
|
||||
|
||||
@@ -173,6 +173,7 @@ export default class CreatePost extends React.Component {
|
||||
post.create_at = time;
|
||||
post.root_id = this.state.rootId;
|
||||
post.parent_id = this.state.parentId;
|
||||
post.attachments = [];
|
||||
|
||||
const channel = ChannelStore.get(this.state.channelId);
|
||||
|
||||
|
||||
240
web/react/components/post_attachment.jsx
Обычный файл
240
web/react/components/post_attachment.jsx
Обычный файл
@@ -0,0 +1,240 @@
|
||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
const TextFormatting = require('../utils/text_formatting.jsx');
|
||||
|
||||
export default class PostAttachment extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.getFieldsTable = this.getFieldsTable.bind(this);
|
||||
}
|
||||
|
||||
getFieldsTable() {
|
||||
const fields = this.props.attachment.fields;
|
||||
if (!fields || !fields.length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const compactTable = fields.filter((field) => field.short).length > 0;
|
||||
let tHead;
|
||||
let tBody;
|
||||
|
||||
if (compactTable) {
|
||||
let headerCols = [];
|
||||
let bodyCols = [];
|
||||
|
||||
fields.forEach((field, i) => {
|
||||
headerCols.push(
|
||||
<th
|
||||
className='attachment___field-caption'
|
||||
key={'attachment__field-caption-' + i}
|
||||
>
|
||||
{field.title}
|
||||
</th>
|
||||
);
|
||||
bodyCols.push(
|
||||
<td
|
||||
className='attachment___field'
|
||||
key={'attachment__field-' + i}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(field.value || '')}}
|
||||
>
|
||||
</td>
|
||||
);
|
||||
});
|
||||
|
||||
tHead = (
|
||||
<tr>
|
||||
{headerCols}
|
||||
</tr>
|
||||
);
|
||||
tBody = (
|
||||
<tr>
|
||||
{bodyCols}
|
||||
</tr>
|
||||
);
|
||||
} else {
|
||||
tBody = [];
|
||||
|
||||
fields.forEach((field, i) => {
|
||||
tBody.push(
|
||||
<tr key={'attachment__field-' + i}>
|
||||
<td
|
||||
className='attachment___field-caption'
|
||||
>
|
||||
{field.title}
|
||||
</td>
|
||||
<td
|
||||
className='attachment___field'
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(field.value || '')}}
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<table
|
||||
className='attachment___fields'
|
||||
>
|
||||
<thead>
|
||||
{tHead}
|
||||
</thead>
|
||||
<tbody>
|
||||
{tBody}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const data = this.props.attachment;
|
||||
|
||||
let preText;
|
||||
if (data.pretext) {
|
||||
preText = (
|
||||
<div
|
||||
className='attachment__thumb-pretext'
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(data.pretext)}}
|
||||
>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let author = [];
|
||||
if (data.author_name || data.author_icon) {
|
||||
if (data.author_icon) {
|
||||
author.push(
|
||||
<img
|
||||
className='attachment__author-icon'
|
||||
src={data.author_icon}
|
||||
key={'attachment__author-icon'}
|
||||
height='14'
|
||||
width='14'
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (data.author_name) {
|
||||
author.push(
|
||||
<span
|
||||
className='attachment__author-name'
|
||||
key={'attachment__author-name'}
|
||||
>
|
||||
{data.author_name}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
if (data.author_link) {
|
||||
author = (
|
||||
<a
|
||||
href={data.author_link}
|
||||
target='_blank'
|
||||
>
|
||||
{author}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
let title;
|
||||
if (data.title) {
|
||||
if (data.title_link) {
|
||||
title = (
|
||||
<h1
|
||||
className='attachment__title'
|
||||
>
|
||||
<a
|
||||
className='attachment__title-link'
|
||||
href={data.title_link}
|
||||
target='_blank'
|
||||
>
|
||||
{data.title}
|
||||
</a>
|
||||
</h1>
|
||||
);
|
||||
} else {
|
||||
title = (
|
||||
<h1
|
||||
className='attachment__title'
|
||||
>
|
||||
{data.title}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let text;
|
||||
if (data.text) {
|
||||
text = (
|
||||
<div
|
||||
className='attachment__text'
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(data.text || '')}}
|
||||
>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let image;
|
||||
if (data.image_url) {
|
||||
image = (
|
||||
<img
|
||||
className='attachment__image'
|
||||
src={data.image_url}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let thumb;
|
||||
if (data.thumb_url) {
|
||||
thumb = (
|
||||
<div
|
||||
className='attachment__thumb-container'
|
||||
>
|
||||
<img
|
||||
src={data.thumb_url}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const fields = this.getFieldsTable();
|
||||
|
||||
let useBorderStyle;
|
||||
if (data.color && data.color[0] === '#') {
|
||||
useBorderStyle = {borderLeftColor: data.color};
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className='attachment'
|
||||
>
|
||||
{preText}
|
||||
<div className='attachment__content'>
|
||||
<div
|
||||
className={useBorderStyle ? 'attachment__container' : 'attachment__container attachment__container--' + data.color}
|
||||
style={useBorderStyle}
|
||||
>
|
||||
{author}
|
||||
{title}
|
||||
<div>
|
||||
<div
|
||||
className={thumb ? 'attachment__body' : 'attachment__body attachment__body--no_thumb'}
|
||||
>
|
||||
{text}
|
||||
{image}
|
||||
{fields}
|
||||
</div>
|
||||
{thumb}
|
||||
<div style={{clear: 'both'}}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PostAttachment.propTypes = {
|
||||
attachment: React.PropTypes.object.isRequired
|
||||
};
|
||||
32
web/react/components/post_attachment_list.jsx
Обычный файл
32
web/react/components/post_attachment_list.jsx
Обычный файл
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
const PostAttachment = require('./post_attachment.jsx');
|
||||
|
||||
export default class PostAttachmentList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
let content = [];
|
||||
this.props.attachments.forEach((attachment, i) => {
|
||||
content.push(
|
||||
<PostAttachment
|
||||
attachment={attachment}
|
||||
key={'att_' + i}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className='attachment_list'>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PostAttachmentList.propTypes = {
|
||||
attachments: React.PropTypes.array.isRequired
|
||||
};
|
||||
@@ -7,6 +7,7 @@ const Utils = require('../utils/utils.jsx');
|
||||
const Constants = require('../utils/constants.jsx');
|
||||
const TextFormatting = require('../utils/text_formatting.jsx');
|
||||
const twemoji = require('twemoji');
|
||||
const PostAttachmentList = require('./post_attachment_list.jsx');
|
||||
|
||||
export default class PostBody extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -316,6 +317,15 @@ export default class PostBody extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
let postAttachments = '';
|
||||
if (post.attachments && post.attachments.length) {
|
||||
postAttachments = (
|
||||
<PostAttachmentList
|
||||
attachments={post.attachments}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='post-body'>
|
||||
{comment}
|
||||
@@ -331,6 +341,7 @@ export default class PostBody extends React.Component {
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.state.message)}}
|
||||
/>
|
||||
</div>
|
||||
{postAttachments}
|
||||
{fileAttachmentHolder}
|
||||
{embed}
|
||||
</div>
|
||||
|
||||
Ссылка в новой задаче
Block a user