|
|
@ -163,7 +163,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<img
|
|
|
|
<img
|
|
|
|
className={`img-fluid thumbnail rounded ${
|
|
|
|
className={`img-fluid thumbnail rounded ${
|
|
|
|
(post.nsfw || post.community_nsfw) && 'img-blur'
|
|
|
|
post.nsfw || post.community_nsfw ? 'img-blur' : ''
|
|
|
|
}`}
|
|
|
|
}`}
|
|
|
|
src={src}
|
|
|
|
src={src}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
@ -190,8 +190,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
|
|
|
|
|
|
|
|
if (isImage(post.url)) {
|
|
|
|
if (isImage(post.url)) {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<span
|
|
|
|
<div
|
|
|
|
class="text-body pointer"
|
|
|
|
class="text-body pointer d-inline-block position-relative"
|
|
|
|
data-tippy-content={i18n.t('expand_here')}
|
|
|
|
data-tippy-content={i18n.t('expand_here')}
|
|
|
|
onClick={linkEvent(this, this.handleImageExpandClick)}
|
|
|
|
onClick={linkEvent(this, this.handleImageExpandClick)}
|
|
|
|
>
|
|
|
|
>
|
|
|
@ -199,12 +199,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
<svg class="icon mini-overlay">
|
|
|
|
<svg class="icon mini-overlay">
|
|
|
|
<use xlinkHref="#icon-image"></use>
|
|
|
|
<use xlinkHref="#icon-image"></use>
|
|
|
|
</svg>
|
|
|
|
</svg>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
} else if (post.thumbnail_url) {
|
|
|
|
} else if (post.thumbnail_url) {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<a
|
|
|
|
<a
|
|
|
|
className="text-body"
|
|
|
|
class="text-body d-inline-block position-relative"
|
|
|
|
href={post.url}
|
|
|
|
href={post.url}
|
|
|
|
target="_blank"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener"
|
|
|
|
rel="noopener"
|
|
|
@ -265,10 +265,93 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
listing() {
|
|
|
|
createdLine() {
|
|
|
|
let post = this.props.post;
|
|
|
|
let post = this.props.post;
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div class="row">
|
|
|
|
<ul class="list-inline mb-1 text-muted small">
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
|
|
|
|
<UserListing
|
|
|
|
|
|
|
|
user={{
|
|
|
|
|
|
|
|
name: post.creator_name,
|
|
|
|
|
|
|
|
preferred_username: post.creator_preferred_username,
|
|
|
|
|
|
|
|
avatar: post.creator_avatar,
|
|
|
|
|
|
|
|
id: post.creator_id,
|
|
|
|
|
|
|
|
local: post.creator_local,
|
|
|
|
|
|
|
|
actor_id: post.creator_actor_id,
|
|
|
|
|
|
|
|
published: post.creator_published,
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{this.isMod && (
|
|
|
|
|
|
|
|
<span className="mx-1 badge badge-light">{i18n.t('mod')}</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{this.isAdmin && (
|
|
|
|
|
|
|
|
<span className="mx-1 badge badge-light">{i18n.t('admin')}</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{(post.banned_from_community || post.banned) && (
|
|
|
|
|
|
|
|
<span className="mx-1 badge badge-danger">{i18n.t('banned')}</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{this.props.showCommunity && (
|
|
|
|
|
|
|
|
<span>
|
|
|
|
|
|
|
|
<span class="mx-1"> {i18n.t('to')} </span>
|
|
|
|
|
|
|
|
<CommunityLink
|
|
|
|
|
|
|
|
community={{
|
|
|
|
|
|
|
|
name: post.community_name,
|
|
|
|
|
|
|
|
id: post.community_id,
|
|
|
|
|
|
|
|
local: post.community_local,
|
|
|
|
|
|
|
|
actor_id: post.community_actor_id,
|
|
|
|
|
|
|
|
icon: post.community_icon,
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
<li className="list-inline-item">•</li>
|
|
|
|
|
|
|
|
{post.url && !(hostname(post.url) == window.location.hostname) && (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
|
|
|
|
<a
|
|
|
|
|
|
|
|
className="text-muted font-italic"
|
|
|
|
|
|
|
|
href={post.url}
|
|
|
|
|
|
|
|
target="_blank"
|
|
|
|
|
|
|
|
title={post.url}
|
|
|
|
|
|
|
|
rel="noopener"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{hostname(post.url)}
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
<li className="list-inline-item">•</li>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
|
|
|
|
<span>
|
|
|
|
|
|
|
|
<MomentTime data={post} />
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
{post.body && (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<li className="list-inline-item">•</li>
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
|
|
|
|
{/* Using a link with tippy doesn't work on touch devices unfortunately */}
|
|
|
|
|
|
|
|
<Link
|
|
|
|
|
|
|
|
className="text-muted"
|
|
|
|
|
|
|
|
data-tippy-content={md.render(previewLines(post.body))}
|
|
|
|
|
|
|
|
data-tippy-allowHtml={true}
|
|
|
|
|
|
|
|
to={`/post/${post.id}`}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<svg class="mr-1 icon icon-inline">
|
|
|
|
|
|
|
|
<use xlinkHref="#icon-book-open"></use>
|
|
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
voteBar() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={`vote-bar col-1 pr-0 small text-center`}>
|
|
|
|
<div className={`vote-bar col-1 pr-0 small text-center`}>
|
|
|
|
<button
|
|
|
|
<button
|
|
|
|
className={`btn-animate btn btn-link p-0 ${
|
|
|
|
className={`btn-animate btn btn-link p-0 ${
|
|
|
@ -301,18 +384,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{!this.state.imageExpanded && (
|
|
|
|
);
|
|
|
|
<div class="col-3 col-sm-2 pr-0">
|
|
|
|
}
|
|
|
|
<div class="position-relative">{this.thumbnail()}</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
postTitleLine() {
|
|
|
|
)}
|
|
|
|
let post = this.props.post;
|
|
|
|
<div
|
|
|
|
return (
|
|
|
|
class={`${this.state.imageExpanded ? 'col-12' : 'col-8 col-sm-9'}`}
|
|
|
|
<div className="post-title overflow-hidden">
|
|
|
|
>
|
|
|
|
<h5>
|
|
|
|
<div class="row">
|
|
|
|
|
|
|
|
<div className="col-12">
|
|
|
|
|
|
|
|
<div className="post-title">
|
|
|
|
|
|
|
|
<h5 className="mb-1 d-inline-block">
|
|
|
|
|
|
|
|
{this.props.showBody && post.url ? (
|
|
|
|
{this.props.showBody && post.url ? (
|
|
|
|
<a
|
|
|
|
<a
|
|
|
|
className={!post.stickied ? 'text-body' : 'text-primary'}
|
|
|
|
className={!post.stickied ? 'text-body' : 'text-primary'}
|
|
|
@ -332,23 +411,6 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
{post.name}
|
|
|
|
{post.name}
|
|
|
|
</Link>
|
|
|
|
</Link>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</h5>
|
|
|
|
|
|
|
|
{post.url && !(hostname(post.url) == window.location.hostname) && (
|
|
|
|
|
|
|
|
<small class="d-inline-block">
|
|
|
|
|
|
|
|
<a
|
|
|
|
|
|
|
|
className="ml-2 text-muted font-italic"
|
|
|
|
|
|
|
|
href={post.url}
|
|
|
|
|
|
|
|
target="_blank"
|
|
|
|
|
|
|
|
title={post.url}
|
|
|
|
|
|
|
|
rel="noopener"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{hostname(post.url)}
|
|
|
|
|
|
|
|
<svg class="ml-1 icon icon-inline">
|
|
|
|
|
|
|
|
<use xlinkHref="#icon-external-link"></use>
|
|
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</small>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{(isImage(post.url) || this.props.post.thumbnail_url) && (
|
|
|
|
{(isImage(post.url) || this.props.post.thumbnail_url) && (
|
|
|
|
<>
|
|
|
|
<>
|
|
|
|
{!this.state.imageExpanded ? (
|
|
|
|
{!this.state.imageExpanded ? (
|
|
|
@ -374,10 +436,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
<div>
|
|
|
|
<div>
|
|
|
|
<span
|
|
|
|
<span
|
|
|
|
class="pointer"
|
|
|
|
class="pointer"
|
|
|
|
onClick={linkEvent(
|
|
|
|
onClick={linkEvent(this, this.handleImageExpandClick)}
|
|
|
|
this,
|
|
|
|
|
|
|
|
this.handleImageExpandClick
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<img
|
|
|
|
<img
|
|
|
|
class="img-fluid img-expanded"
|
|
|
|
class="img-fluid img-expanded"
|
|
|
@ -429,82 +488,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
{i18n.t('nsfw')}
|
|
|
|
{i18n.t('nsfw')}
|
|
|
|
</small>
|
|
|
|
</small>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
|
|
|
|
</h5>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
<div class="row">
|
|
|
|
|
|
|
|
<div className="details col-12">
|
|
|
|
|
|
|
|
<ul class="list-inline mb-1 text-muted small">
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
|
|
|
|
<span>{i18n.t('by')} </span>
|
|
|
|
|
|
|
|
<UserListing
|
|
|
|
|
|
|
|
user={{
|
|
|
|
|
|
|
|
name: post.creator_name,
|
|
|
|
|
|
|
|
preferred_username: post.creator_preferred_username,
|
|
|
|
|
|
|
|
avatar: post.creator_avatar,
|
|
|
|
|
|
|
|
id: post.creator_id,
|
|
|
|
|
|
|
|
local: post.creator_local,
|
|
|
|
|
|
|
|
actor_id: post.creator_actor_id,
|
|
|
|
|
|
|
|
published: post.creator_published,
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{this.isMod && (
|
|
|
|
commentsLine(showVotes: boolean = false) {
|
|
|
|
<span className="mx-1 badge badge-light">
|
|
|
|
let post = this.props.post;
|
|
|
|
{i18n.t('mod')}
|
|
|
|
return (
|
|
|
|
</span>
|
|
|
|
<ul class="d-flex align-items-center list-inline mb-1 text-muted small">
|
|
|
|
)}
|
|
|
|
|
|
|
|
{this.isAdmin && (
|
|
|
|
|
|
|
|
<span className="mx-1 badge badge-light">
|
|
|
|
|
|
|
|
{i18n.t('admin')}
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{(post.banned_from_community || post.banned) && (
|
|
|
|
|
|
|
|
<span className="mx-1 badge badge-danger">
|
|
|
|
|
|
|
|
{i18n.t('banned')}
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{this.props.showCommunity && (
|
|
|
|
|
|
|
|
<span>
|
|
|
|
|
|
|
|
<span> {i18n.t('to')} </span>
|
|
|
|
|
|
|
|
<CommunityLink
|
|
|
|
|
|
|
|
community={{
|
|
|
|
|
|
|
|
name: post.community_name,
|
|
|
|
|
|
|
|
id: post.community_id,
|
|
|
|
|
|
|
|
local: post.community_local,
|
|
|
|
|
|
|
|
actor_id: post.community_actor_id,
|
|
|
|
|
|
|
|
icon: post.community_icon,
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
<li className="list-inline-item">•</li>
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
|
|
|
|
<span>
|
|
|
|
|
|
|
|
<MomentTime data={post} />
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
{post.body && (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<li className="list-inline-item">•</li>
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
|
|
|
|
{/* Using a link with tippy doesn't work on touch devices unfortunately */}
|
|
|
|
|
|
|
|
<Link
|
|
|
|
|
|
|
|
className="text-muted"
|
|
|
|
|
|
|
|
data-tippy-content={md.render(previewLines(post.body))}
|
|
|
|
|
|
|
|
data-tippy-allowHtml={true}
|
|
|
|
|
|
|
|
to={`/post/${post.id}`}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<svg class="mr-1 icon icon-inline">
|
|
|
|
|
|
|
|
<use xlinkHref="#icon-book-open"></use>
|
|
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<ul class="list-inline mb-1 text-muted small">
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
<li className="list-inline-item">
|
|
|
|
<Link
|
|
|
|
<Link
|
|
|
|
className="text-muted"
|
|
|
|
className="text-muted"
|
|
|
@ -521,7 +513,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
})}
|
|
|
|
})}
|
|
|
|
</Link>
|
|
|
|
</Link>
|
|
|
|
</li>
|
|
|
|
</li>
|
|
|
|
{this.state.upvotes !== this.state.score && (
|
|
|
|
{(showVotes || this.state.upvotes !== this.state.score) && (
|
|
|
|
<>
|
|
|
|
<>
|
|
|
|
<li className="list-inline-item">•</li>
|
|
|
|
<li className="list-inline-item">•</li>
|
|
|
|
<span
|
|
|
|
<span
|
|
|
@ -529,26 +521,41 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
data-tippy-content={this.pointsTippy}
|
|
|
|
data-tippy-content={this.pointsTippy}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<li className="list-inline-item">
|
|
|
|
<li className="list-inline-item">
|
|
|
|
<span className="text-muted">
|
|
|
|
<a
|
|
|
|
|
|
|
|
className={`btn-animate btn btn-link p-0 ${
|
|
|
|
|
|
|
|
this.state.my_vote == 1 ? 'text-info' : 'text-muted'
|
|
|
|
|
|
|
|
}`}
|
|
|
|
|
|
|
|
onClick={linkEvent(this, this.handlePostLike)}
|
|
|
|
|
|
|
|
>
|
|
|
|
<svg class="small icon icon-inline mr-1">
|
|
|
|
<svg class="small icon icon-inline mr-1">
|
|
|
|
<use xlinkHref="#icon-arrow-up"></use>
|
|
|
|
<use xlinkHref="#icon-arrow-up"></use>
|
|
|
|
</svg>
|
|
|
|
</svg>
|
|
|
|
{this.state.upvotes}
|
|
|
|
{this.state.upvotes}
|
|
|
|
</span>
|
|
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</li>
|
|
|
|
<li className="list-inline-item">
|
|
|
|
<li className="list-inline-item">
|
|
|
|
<span className="text-muted">
|
|
|
|
<a
|
|
|
|
|
|
|
|
className={`btn-animate btn btn-link p-0 ${
|
|
|
|
|
|
|
|
this.state.my_vote == -1 ? 'text-danger' : 'text-muted'
|
|
|
|
|
|
|
|
}`}
|
|
|
|
|
|
|
|
onClick={linkEvent(this, this.handlePostDisLike)}
|
|
|
|
|
|
|
|
>
|
|
|
|
<svg class="small icon icon-inline mr-1">
|
|
|
|
<svg class="small icon icon-inline mr-1">
|
|
|
|
<use xlinkHref="#icon-arrow-down"></use>
|
|
|
|
<use xlinkHref="#icon-arrow-down"></use>
|
|
|
|
</svg>
|
|
|
|
</svg>
|
|
|
|
{this.state.downvotes}
|
|
|
|
{this.state.downvotes}
|
|
|
|
</span>
|
|
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</li>
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</ul>
|
|
|
|
</ul>
|
|
|
|
{this.props.post.duplicates && (
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
duplicatesLine() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
this.props.post.duplicates && (
|
|
|
|
<ul class="list-inline mb-1 small text-muted">
|
|
|
|
<ul class="list-inline mb-1 small text-muted">
|
|
|
|
<>
|
|
|
|
<>
|
|
|
|
<li className="list-inline-item mr-2">
|
|
|
|
<li className="list-inline-item mr-2">
|
|
|
@ -556,14 +563,18 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
</li>
|
|
|
|
</li>
|
|
|
|
{this.props.post.duplicates.map(post => (
|
|
|
|
{this.props.post.duplicates.map(post => (
|
|
|
|
<li className="list-inline-item mr-2">
|
|
|
|
<li className="list-inline-item mr-2">
|
|
|
|
<Link to={`/post/${post.id}`}>
|
|
|
|
<Link to={`/post/${post.id}`}>{post.community_name}</Link>
|
|
|
|
{post.community_name}
|
|
|
|
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
</li>
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|
</ul>
|
|
|
|
</ul>
|
|
|
|
)}
|
|
|
|
)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
postActions() {
|
|
|
|
|
|
|
|
let post = this.props.post;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ul class="list-inline mb-1 text-muted font-weight-bold">
|
|
|
|
<ul class="list-inline mb-1 text-muted font-weight-bold">
|
|
|
|
{UserService.Instance.user && (
|
|
|
|
{UserService.Instance.user && (
|
|
|
|
<>
|
|
|
|
<>
|
|
|
@ -578,9 +589,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<svg
|
|
|
|
<svg
|
|
|
|
class={`icon icon-inline ${
|
|
|
|
class={`icon icon-inline ${post.saved && 'text-warning'}`}
|
|
|
|
post.saved && 'text-warning'
|
|
|
|
|
|
|
|
}`}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<use xlinkHref="#icon-star"></use>
|
|
|
|
<use xlinkHref="#icon-star"></use>
|
|
|
|
</svg>
|
|
|
|
</svg>
|
|
|
@ -617,9 +626,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
class="btn btn-link btn-animate text-muted"
|
|
|
|
class="btn btn-link btn-animate text-muted"
|
|
|
|
onClick={linkEvent(this, this.handleDeleteClick)}
|
|
|
|
onClick={linkEvent(this, this.handleDeleteClick)}
|
|
|
|
data-tippy-content={
|
|
|
|
data-tippy-content={
|
|
|
|
!post.deleted
|
|
|
|
!post.deleted ? i18n.t('delete') : i18n.t('restore')
|
|
|
|
? i18n.t('delete')
|
|
|
|
|
|
|
|
: i18n.t('restore')
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<svg
|
|
|
|
<svg
|
|
|
@ -672,9 +679,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
class="btn btn-link btn-animate text-muted"
|
|
|
|
class="btn btn-link btn-animate text-muted"
|
|
|
|
onClick={linkEvent(this, this.handleModLock)}
|
|
|
|
onClick={linkEvent(this, this.handleModLock)}
|
|
|
|
data-tippy-content={
|
|
|
|
data-tippy-content={
|
|
|
|
post.locked
|
|
|
|
post.locked ? i18n.t('unlock') : i18n.t('lock')
|
|
|
|
? i18n.t('unlock')
|
|
|
|
|
|
|
|
: i18n.t('lock')
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<svg
|
|
|
|
<svg
|
|
|
@ -691,9 +696,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
class="btn btn-link btn-animate text-muted"
|
|
|
|
class="btn btn-link btn-animate text-muted"
|
|
|
|
onClick={linkEvent(this, this.handleModSticky)}
|
|
|
|
onClick={linkEvent(this, this.handleModSticky)}
|
|
|
|
data-tippy-content={
|
|
|
|
data-tippy-content={
|
|
|
|
post.stickied
|
|
|
|
post.stickied ? i18n.t('unsticky') : i18n.t('sticky')
|
|
|
|
? i18n.t('unsticky')
|
|
|
|
|
|
|
|
: i18n.t('sticky')
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<svg
|
|
|
|
<svg
|
|
|
@ -713,20 +716,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
{!post.removed ? (
|
|
|
|
{!post.removed ? (
|
|
|
|
<span
|
|
|
|
<span
|
|
|
|
class="pointer"
|
|
|
|
class="pointer"
|
|
|
|
onClick={linkEvent(
|
|
|
|
onClick={linkEvent(this, this.handleModRemoveShow)}
|
|
|
|
this,
|
|
|
|
|
|
|
|
this.handleModRemoveShow
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{i18n.t('remove')}
|
|
|
|
{i18n.t('remove')}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
) : (
|
|
|
|
) : (
|
|
|
|
<span
|
|
|
|
<span
|
|
|
|
class="pointer"
|
|
|
|
class="pointer"
|
|
|
|
onClick={linkEvent(
|
|
|
|
onClick={linkEvent(this, this.handleModRemoveSubmit)}
|
|
|
|
this,
|
|
|
|
|
|
|
|
this.handleModRemoveSubmit
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{i18n.t('restore')}
|
|
|
|
{i18n.t('restore')}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
@ -778,8 +775,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
{/* Community creators and admins can transfer community to another mod */}
|
|
|
|
{/* Community creators and admins can transfer community to another mod */}
|
|
|
|
{(this.amCommunityCreator || this.canAdmin) &&
|
|
|
|
{(this.amCommunityCreator || this.canAdmin) && this.isMod && (
|
|
|
|
this.isMod && (
|
|
|
|
|
|
|
|
<li className="list-inline-item">
|
|
|
|
<li className="list-inline-item">
|
|
|
|
{!this.state.showConfirmTransferCommunity ? (
|
|
|
|
{!this.state.showConfirmTransferCommunity ? (
|
|
|
|
<span
|
|
|
|
<span
|
|
|
@ -809,8 +805,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
class="pointer d-inline-block"
|
|
|
|
class="pointer d-inline-block"
|
|
|
|
onClick={linkEvent(
|
|
|
|
onClick={linkEvent(
|
|
|
|
this,
|
|
|
|
this,
|
|
|
|
this
|
|
|
|
this.handleCancelShowConfirmTransferCommunity
|
|
|
|
.handleCancelShowConfirmTransferCommunity
|
|
|
|
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{i18n.t('no')}
|
|
|
|
{i18n.t('no')}
|
|
|
@ -827,20 +822,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
{!post.banned ? (
|
|
|
|
{!post.banned ? (
|
|
|
|
<span
|
|
|
|
<span
|
|
|
|
class="pointer"
|
|
|
|
class="pointer"
|
|
|
|
onClick={linkEvent(
|
|
|
|
onClick={linkEvent(this, this.handleModBanShow)}
|
|
|
|
this,
|
|
|
|
|
|
|
|
this.handleModBanShow
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{i18n.t('ban_from_site')}
|
|
|
|
{i18n.t('ban_from_site')}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
) : (
|
|
|
|
) : (
|
|
|
|
<span
|
|
|
|
<span
|
|
|
|
class="pointer"
|
|
|
|
class="pointer"
|
|
|
|
onClick={linkEvent(
|
|
|
|
onClick={linkEvent(this, this.handleModBanSubmit)}
|
|
|
|
this,
|
|
|
|
|
|
|
|
this.handleModBanSubmit
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{i18n.t('unban_from_site')}
|
|
|
|
{i18n.t('unban_from_site')}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
@ -881,10 +870,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
<span
|
|
|
|
<span
|
|
|
|
class="pointer d-inline-block mr-1"
|
|
|
|
class="pointer d-inline-block mr-1"
|
|
|
|
onClick={linkEvent(
|
|
|
|
onClick={linkEvent(this, this.handleTransferSite)}
|
|
|
|
this,
|
|
|
|
|
|
|
|
this.handleTransferSite
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{i18n.t('yes')}
|
|
|
|
{i18n.t('yes')}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
@ -906,6 +892,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
</ul>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
removeAndBanDialogs() {
|
|
|
|
|
|
|
|
let post = this.props.post;
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
{this.state.showRemoveDialog && (
|
|
|
|
{this.state.showRemoveDialog && (
|
|
|
|
<form
|
|
|
|
<form
|
|
|
|
class="form-inline"
|
|
|
|
class="form-inline"
|
|
|
@ -950,10 +943,89 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</form>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mobileThumbnail() {
|
|
|
|
|
|
|
|
return this.props.post.thumbnail_url || isImage(this.props.post.url) ? (
|
|
|
|
|
|
|
|
<div class="row">
|
|
|
|
|
|
|
|
<div class="col-8">{this.postTitleLine()}</div>
|
|
|
|
|
|
|
|
<div class="col-4">
|
|
|
|
|
|
|
|
{/* Post body prev or thumbnail */}
|
|
|
|
|
|
|
|
{!this.state.imageExpanded && this.thumbnail()}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
this.postTitleLine()
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
showMobilePreview() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
this.props.post.body &&
|
|
|
|
|
|
|
|
!this.props.showBody && (
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
className="md-div mb-1"
|
|
|
|
|
|
|
|
dangerouslySetInnerHTML={{
|
|
|
|
|
|
|
|
__html: md.render(previewLines(this.props.post.body)),
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
listing() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
{/* The mobile view*/}
|
|
|
|
|
|
|
|
<div class="d-block d-sm-none">
|
|
|
|
|
|
|
|
<div class="row">
|
|
|
|
|
|
|
|
<div class="col-12">
|
|
|
|
|
|
|
|
{this.createdLine()}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* If it has a thumbnail, do a right aligned thumbnail */}
|
|
|
|
|
|
|
|
{this.mobileThumbnail()}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* Show a preview of the post body */}
|
|
|
|
|
|
|
|
{this.showMobilePreview()}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{this.commentsLine(true)}
|
|
|
|
|
|
|
|
{this.duplicatesLine()}
|
|
|
|
|
|
|
|
{this.postActions()}
|
|
|
|
|
|
|
|
{this.removeAndBanDialogs()}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* The larger view*/}
|
|
|
|
|
|
|
|
<div class="d-none d-sm-block">
|
|
|
|
|
|
|
|
<div class="row">
|
|
|
|
|
|
|
|
{this.voteBar()}
|
|
|
|
|
|
|
|
{!this.state.imageExpanded && (
|
|
|
|
|
|
|
|
<div class="col-sm-2 pr-0">
|
|
|
|
|
|
|
|
<div class="">{this.thumbnail()}</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
class={`${
|
|
|
|
|
|
|
|
this.state.imageExpanded ? 'col-12' : 'col-12 col-sm-9'
|
|
|
|
|
|
|
|
}`}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<div class="row">
|
|
|
|
|
|
|
|
<div className="col-12">
|
|
|
|
|
|
|
|
{this.postTitleLine()}
|
|
|
|
|
|
|
|
{this.createdLine()}
|
|
|
|
|
|
|
|
{this.commentsLine()}
|
|
|
|
|
|
|
|
{this.duplicatesLine()}
|
|
|
|
|
|
|
|
{this.postActions()}
|
|
|
|
|
|
|
|
{this.removeAndBanDialogs()}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|