Posts structure improvement
Этот коммит содержится в:
@@ -27,6 +27,7 @@ const ActionTypes = Constants.ActionTypes;
|
||||
|
||||
const Popover = ReactBootstrap.Popover;
|
||||
const OverlayTrigger = ReactBootstrap.OverlayTrigger;
|
||||
const Tooltip = ReactBootstrap.Tooltip;
|
||||
|
||||
export default class ChannelHeader extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -121,6 +122,7 @@ export default class ChannelHeader extends React.Component {
|
||||
}
|
||||
|
||||
const channel = this.state.channel;
|
||||
const recentMentionsTooltip = <Tooltip id='recentMentionsTooltip'>{'Recent Mentions'}</Tooltip>;
|
||||
const popoverContent = (
|
||||
<Popover
|
||||
id='hader-popover'
|
||||
@@ -382,31 +384,19 @@ export default class ChannelHeader extends React.Component {
|
||||
<th className='search-bar__container'><NavbarSearchBox /></th>
|
||||
<th>
|
||||
<div className='dropdown channel-header__links'>
|
||||
<a
|
||||
href='#'
|
||||
className='dropdown-toggle theme'
|
||||
type='button'
|
||||
id='channel_header_right_dropdown'
|
||||
data-toggle='dropdown'
|
||||
aria-expanded='true'
|
||||
<OverlayTrigger
|
||||
delayShow={400}
|
||||
placement='bottom'
|
||||
overlay={recentMentionsTooltip}
|
||||
>
|
||||
<span dangerouslySetInnerHTML={{__html: Constants.MENU_ICON}} />
|
||||
</a>
|
||||
<ul
|
||||
className='dropdown-menu dropdown-menu-right'
|
||||
role='menu'
|
||||
aria-labelledby='channel_header_right_dropdown'
|
||||
>
|
||||
<li role='presentation'>
|
||||
<a
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={this.searchMentions}
|
||||
>
|
||||
{'Recent Mentions'}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<a
|
||||
href='#'
|
||||
type='button'
|
||||
onClick={this.searchMentions}
|
||||
>
|
||||
{'@'}
|
||||
</a>
|
||||
</OverlayTrigger>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
@@ -141,6 +141,8 @@ export default class Post extends React.Component {
|
||||
var postType = '';
|
||||
if (type !== 'Post') {
|
||||
postType = 'post--comment';
|
||||
} else if (commentCount > 0) {
|
||||
postType = 'post--root';
|
||||
}
|
||||
|
||||
var currentUserCss = '';
|
||||
@@ -170,14 +172,11 @@ export default class Post extends React.Component {
|
||||
}
|
||||
|
||||
profilePic = (
|
||||
<div className='post-profile-img__container'>
|
||||
<img
|
||||
className='post-profile-img'
|
||||
src={src}
|
||||
height='36'
|
||||
width='36'
|
||||
/>
|
||||
</div>
|
||||
<img
|
||||
src={src}
|
||||
height='36'
|
||||
width='36'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -187,32 +186,26 @@ export default class Post extends React.Component {
|
||||
id={'post_' + post.id}
|
||||
className={'post ' + sameUserClass + ' ' + rootUser + ' ' + postType + ' ' + currentUserCss}
|
||||
>
|
||||
{profilePic}
|
||||
<div className='post__content'>
|
||||
<PostHeader
|
||||
ref='header'
|
||||
post={post}
|
||||
sameRoot={this.props.sameRoot}
|
||||
commentCount={commentCount}
|
||||
handleCommentClick={this.handleCommentClick}
|
||||
isLastComment={this.props.isLastComment}
|
||||
/>
|
||||
<PostBody
|
||||
post={post}
|
||||
sameRoot={this.props.sameRoot}
|
||||
parentPost={parentPost}
|
||||
posts={posts}
|
||||
handleCommentClick={this.handleCommentClick}
|
||||
retryPost={this.retryPost}
|
||||
/>
|
||||
<PostInfo
|
||||
ref='info'
|
||||
post={post}
|
||||
sameRoot={this.props.sameRoot}
|
||||
commentCount={commentCount}
|
||||
handleCommentClick={this.handleCommentClick}
|
||||
allowReply='true'
|
||||
/>
|
||||
<div className='post__img'>{profilePic}</div>
|
||||
<div>
|
||||
<PostHeader
|
||||
ref='header'
|
||||
post={post}
|
||||
sameRoot={this.props.sameRoot}
|
||||
commentCount={commentCount}
|
||||
handleCommentClick={this.handleCommentClick}
|
||||
isLastComment={this.props.isLastComment}
|
||||
/>
|
||||
<PostBody
|
||||
post={post}
|
||||
sameRoot={this.props.sameRoot}
|
||||
parentPost={parentPost}
|
||||
posts={posts}
|
||||
handleCommentClick={this.handleCommentClick}
|
||||
retryPost={this.retryPost}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -257,7 +257,7 @@ export default class PostBody extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='post-comment'>
|
||||
<div>
|
||||
<h4>
|
||||
<span className='video-type'>{header}</span>
|
||||
<span className='video-title'><a href={link}>{this.state.youtubeTitle}</a></span>
|
||||
@@ -329,7 +329,7 @@ export default class PostBody extends React.Component {
|
||||
}
|
||||
|
||||
comment = (
|
||||
<p className='post-link'>
|
||||
<div className='post__link'>
|
||||
<span>
|
||||
{'Commented on '}{name}{apostrophe}{' message: '}
|
||||
<a
|
||||
@@ -339,15 +339,13 @@ export default class PostBody extends React.Component {
|
||||
{message}
|
||||
</a>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
postClass += ' post-comment';
|
||||
}
|
||||
|
||||
let loading;
|
||||
if (post.state === Constants.POST_FAILED) {
|
||||
postClass += ' post-fail';
|
||||
postClass += ' post--fail';
|
||||
loading = (
|
||||
<a
|
||||
className='theme post-retry pull-right'
|
||||
@@ -379,25 +377,27 @@ export default class PostBody extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='post-body'>
|
||||
<div>
|
||||
{comment}
|
||||
<div
|
||||
key={`${post.id}_message`}
|
||||
id={`${post.id}_message`}
|
||||
className={postClass}
|
||||
>
|
||||
{loading}
|
||||
<span
|
||||
ref='message_span'
|
||||
onClick={TextFormatting.handleClick}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.state.message)}}
|
||||
<div className='post__body'>
|
||||
<div
|
||||
key={`${post.id}_message`}
|
||||
id={`${post.id}_message`}
|
||||
className={postClass}
|
||||
>
|
||||
{loading}
|
||||
<span
|
||||
ref='message_span'
|
||||
onClick={TextFormatting.handleClick}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.state.message)}}
|
||||
/>
|
||||
</div>
|
||||
<PostBodyAdditionalContent
|
||||
post={this.state.post}
|
||||
/>
|
||||
{fileAttachmentHolder}
|
||||
{this.embed}
|
||||
</div>
|
||||
<PostBodyAdditionalContent
|
||||
post={this.state.post}
|
||||
/>
|
||||
{fileAttachmentHolder}
|
||||
{this.embed}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,14 +26,14 @@ export default class PostHeader extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
botIndicator = <li className='post-header-col post-header__name bot-indicator'>{'BOT'}</li>;
|
||||
botIndicator = <li className='col col__name bot-indicator'>{'BOT'}</li>;
|
||||
}
|
||||
|
||||
return (
|
||||
<ul className='post-header post-header-post'>
|
||||
<li className='post-header-col post-header__name'><strong>{userProfile}</strong></li>
|
||||
<ul className='post__header'>
|
||||
<li className='col col__name'>{userProfile}</li>
|
||||
{botIndicator}
|
||||
<li className='post-info--hidden'>
|
||||
<li className='col'>
|
||||
<PostInfo
|
||||
post={post}
|
||||
commentCount={this.props.commentCount}
|
||||
|
||||
@@ -74,23 +74,6 @@ export default class PostInfo extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.allowReply === 'true') {
|
||||
dropdownContents.push(
|
||||
<li
|
||||
key='replyLink'
|
||||
role='presentation'
|
||||
>
|
||||
<a
|
||||
className='reply-link theme'
|
||||
href='#'
|
||||
onClick={this.props.handleCommentClick}
|
||||
>
|
||||
{'Reply'}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
if (dropdownContents.length === 0) {
|
||||
return '';
|
||||
}
|
||||
@@ -99,7 +82,7 @@ export default class PostInfo extends React.Component {
|
||||
<div>
|
||||
<a
|
||||
href='#'
|
||||
className='dropdown-toggle theme'
|
||||
className='dropdown-toggle post__dropdown theme'
|
||||
type='button'
|
||||
data-toggle='dropdown'
|
||||
aria-expanded='false'
|
||||
@@ -116,23 +99,27 @@ export default class PostInfo extends React.Component {
|
||||
render() {
|
||||
var post = this.props.post;
|
||||
var comments = '';
|
||||
var lastCommentClass = ' comment-icon__container__hide';
|
||||
if (this.props.isLastComment) {
|
||||
lastCommentClass = ' comment-icon__container__show';
|
||||
var showCommentClass = '';
|
||||
var commentCountText = this.props.commentCount;
|
||||
|
||||
if (this.props.commentCount >= 1) {
|
||||
showCommentClass = ' icon--show';
|
||||
} else {
|
||||
commentCountText = '';
|
||||
}
|
||||
|
||||
if (this.props.commentCount >= 1 && post.state !== Constants.POST_FAILED && post.state !== Constants.POST_LOADING && post.state !== Constants.POST_DELETED) {
|
||||
if (post.state !== Constants.POST_FAILED && post.state !== Constants.POST_LOADING && post.state !== Constants.POST_DELETED) {
|
||||
comments = (
|
||||
<a
|
||||
href='#'
|
||||
className={'comment-icon__container theme' + lastCommentClass}
|
||||
className={'comment-icon__container' + showCommentClass}
|
||||
onClick={this.props.handleCommentClick}
|
||||
>
|
||||
<span
|
||||
className='comment-icon'
|
||||
dangerouslySetInnerHTML={{__html: Constants.COMMENT_ICON}}
|
||||
/>
|
||||
{this.props.commentCount}
|
||||
{commentCountText}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
@@ -140,17 +127,17 @@ export default class PostInfo extends React.Component {
|
||||
var dropdown = this.createDropdown();
|
||||
|
||||
return (
|
||||
<ul className='post-header post-info'>
|
||||
<li className='post-header-col'>
|
||||
<ul className='post__header post__header--info'>
|
||||
<li className='col'>
|
||||
<TimeSince
|
||||
eventTime={post.create_at}
|
||||
/>
|
||||
</li>
|
||||
<li className='post-header-col post-header__reply'>
|
||||
<li className='col col__reply'>
|
||||
{comments}
|
||||
<div className='dropdown'>
|
||||
{dropdown}
|
||||
</div>
|
||||
{comments}
|
||||
</li>
|
||||
</ul>
|
||||
);
|
||||
|
||||
@@ -131,7 +131,7 @@ export default class RhsComment extends React.Component {
|
||||
<div className='dropdown'>
|
||||
<a
|
||||
href='#'
|
||||
className='dropdown-toggle theme'
|
||||
className='post__dropdown dropdown-toggle'
|
||||
type='button'
|
||||
data-toggle='dropdown'
|
||||
aria-expanded='false'
|
||||
@@ -193,38 +193,39 @@ export default class RhsComment extends React.Component {
|
||||
|
||||
return (
|
||||
<div className={'post ' + currentUserCss}>
|
||||
<div className='post-profile-img__container'>
|
||||
<img
|
||||
className='post-profile-img'
|
||||
src={'/api/v1/users/' + post.user_id + '/image?time=' + timestamp + '&' + Utils.getSessionIndex()}
|
||||
height='36'
|
||||
width='36'
|
||||
/>
|
||||
</div>
|
||||
<div className='post__content'>
|
||||
<ul className='post-header'>
|
||||
<li className='post-header-col'>
|
||||
<strong><UserProfile userId={post.user_id} /></strong>
|
||||
</li>
|
||||
<li className='post-header-col'>
|
||||
<time className='post-profile-time'>
|
||||
{Utils.displayCommentDateTime(post.create_at)}
|
||||
</time>
|
||||
</li>
|
||||
<li className='post-header-col post-header__reply'>
|
||||
{dropdown}
|
||||
</li>
|
||||
</ul>
|
||||
<div className='post-body'>
|
||||
<div className={postClass}>
|
||||
{loading}
|
||||
<div
|
||||
ref='message_holder'
|
||||
onClick={TextFormatting.handleClick}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}}
|
||||
/>
|
||||
<div className='post__img'>
|
||||
<img
|
||||
src={'/api/v1/users/' + post.user_id + '/image?time=' + timestamp + '&' + Utils.getSessionIndex()}
|
||||
height='36'
|
||||
width='36'
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<ul className='post__header'>
|
||||
<li className='col__name'>
|
||||
<strong><UserProfile userId={post.user_id} /></strong>
|
||||
</li>
|
||||
<li className='col'>
|
||||
<time className='post__time'>
|
||||
{Utils.displayCommentDateTime(post.create_at)}
|
||||
</time>
|
||||
</li>
|
||||
<li className='col col__reply'>
|
||||
{dropdown}
|
||||
</li>
|
||||
</ul>
|
||||
<div className='post__body'>
|
||||
<div className={postClass}>
|
||||
{loading}
|
||||
<div
|
||||
ref='message_holder'
|
||||
onClick={TextFormatting.handleClick}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}}
|
||||
/>
|
||||
</div>
|
||||
{fileAttachment}
|
||||
</div>
|
||||
{fileAttachment}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -66,7 +66,7 @@ export default class RhsRootPost extends React.Component {
|
||||
ownerOptions = (
|
||||
<div>
|
||||
<a href='#'
|
||||
className='dropdown-toggle theme'
|
||||
className='post__dropdown dropdown-toggle'
|
||||
type='button'
|
||||
data-toggle='dropdown'
|
||||
aria-expanded='false'
|
||||
@@ -129,7 +129,7 @@ export default class RhsRootPost extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
botIndicator = <li className='post-header-col post-header__name bot-indicator'>{'BOT'}</li>;
|
||||
botIndicator = <li className='col col__name bot-indicator'>{'BOT'}</li>;
|
||||
}
|
||||
|
||||
let src = '/api/v1/users/' + post.user_id + '/image?time=' + timestamp + '&' + utils.getSessionIndex();
|
||||
@@ -140,47 +140,47 @@ export default class RhsRootPost extends React.Component {
|
||||
}
|
||||
|
||||
const profilePic = (
|
||||
<div className='post-profile-img__container'>
|
||||
<img
|
||||
className='post-profile-img'
|
||||
src={src}
|
||||
height='36'
|
||||
width='36'
|
||||
/>
|
||||
</div>
|
||||
<img
|
||||
className='post-profile-img'
|
||||
src={src}
|
||||
height='36'
|
||||
width='36'
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={'post post--root ' + currentUserCss}>
|
||||
<div className='post-right-channel__name'>{channelName}</div>
|
||||
<div className='post-profile-img__container'>
|
||||
{profilePic}
|
||||
</div>
|
||||
<div className='post__content'>
|
||||
<ul className='post-header'>
|
||||
<li className='post-header-col'><strong>{userProfile}</strong></li>
|
||||
{botIndicator}
|
||||
<li className='post-header-col'>
|
||||
<time className='post-profile-time'>
|
||||
{utils.displayCommentDateTime(post.create_at)}
|
||||
</time>
|
||||
</li>
|
||||
<li className='post-header-col post-header__reply'>
|
||||
<div className='dropdown'>
|
||||
{ownerOptions}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div className='post-body'>
|
||||
<div
|
||||
ref='message_holder'
|
||||
onClick={TextFormatting.handleClick}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}}
|
||||
/>
|
||||
<PostBodyAdditionalContent
|
||||
post={post}
|
||||
/>
|
||||
{fileAttachment}
|
||||
<div className='post__img'>
|
||||
{profilePic}
|
||||
</div>
|
||||
<div>
|
||||
<ul className='post__header'>
|
||||
<li className='col__name'>{userProfile}</li>
|
||||
{botIndicator}
|
||||
<li className='col'>
|
||||
<time className='post__time'>
|
||||
{utils.displayCommentDateTime(post.create_at)}
|
||||
</time>
|
||||
</li>
|
||||
<li className='col col__reply'>
|
||||
<div className='dropdown'>
|
||||
{ownerOptions}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div className='post__body'>
|
||||
<div
|
||||
ref='message_holder'
|
||||
onClick={TextFormatting.handleClick}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(post.message)}}
|
||||
/>
|
||||
<PostBodyAdditionalContent
|
||||
post={post}
|
||||
/>
|
||||
{fileAttachment}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
@@ -74,29 +74,30 @@ export default class SearchResultsItem extends React.Component {
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
<div className='search-channel__name'>{channelName}</div>
|
||||
<div className='post-profile-img__container'>
|
||||
<img
|
||||
className='post-profile-img'
|
||||
src={'/api/v1/users/' + this.props.post.user_id + '/image?time=' + timestamp + '&' + utils.getSessionIndex()}
|
||||
height='36'
|
||||
width='36'
|
||||
/>
|
||||
</div>
|
||||
<div className='post__content'>
|
||||
<ul className='post-header'>
|
||||
<li className='post-header-col'><strong><UserProfile userId={this.props.post.user_id} /></strong></li>
|
||||
<li className='post-header-col'>
|
||||
<time className='search-item-time'>
|
||||
{utils.displayDate(this.props.post.create_at) + ' ' + utils.displayTime(this.props.post.create_at)}
|
||||
</time>
|
||||
</li>
|
||||
</ul>
|
||||
<div className='search-item-snippet'>
|
||||
<span
|
||||
onClick={this.handleClick}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message, formattingOptions)}}
|
||||
<div className='post__img'>
|
||||
<img
|
||||
src={'/api/v1/users/' + this.props.post.user_id + '/image?time=' + timestamp + '&' + utils.getSessionIndex()}
|
||||
height='36'
|
||||
width='36'
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<ul className='post__header'>
|
||||
<li className='col__name'><strong><UserProfile userId={this.props.post.user_id} /></strong></li>
|
||||
<li className='col'>
|
||||
<time className='search-item-time'>
|
||||
{utils.displayDate(this.props.post.create_at) + ' ' + utils.displayTime(this.props.post.create_at)}
|
||||
</time>
|
||||
</li>
|
||||
</ul>
|
||||
<div className='search-item-snippet'>
|
||||
<span
|
||||
onClick={this.handleClick}
|
||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message, formattingOptions)}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -34,7 +34,7 @@ export default class TimeSince extends React.Component {
|
||||
placement='top'
|
||||
overlay={tooltip}
|
||||
>
|
||||
<time className='post-profile-time'>
|
||||
<time className='post__time'>
|
||||
{Utils.displayDateTime(this.props.eventTime)}
|
||||
</time>
|
||||
</OverlayTrigger>
|
||||
|
||||
@@ -14,7 +14,10 @@ export default class CustomThemeChooser extends React.Component {
|
||||
this.state = {};
|
||||
}
|
||||
componentDidMount() {
|
||||
$('.color-picker').colorpicker().on('changeColor', this.onPickerChange);
|
||||
$('.color-picker').colorpicker({
|
||||
format: 'hex'
|
||||
});
|
||||
$('.color-picker').on('changeColor', this.onPickerChange);
|
||||
}
|
||||
onPickerChange(e) {
|
||||
const theme = this.props.theme;
|
||||
|
||||
Ссылка в новой задаче
Block a user