forked from nutomic/lemmy
parent
ae40c2b08d
commit
a8da6d37c2
3 changed files with 132 additions and 94 deletions
19
ui/src/components/comment-node.tsx
vendored
19
ui/src/components/comment-node.tsx
vendored
|
@ -22,6 +22,7 @@ interface CommentNodeState {
|
||||||
showConfirmTransferSite: boolean;
|
showConfirmTransferSite: boolean;
|
||||||
showConfirmTransferCommunity: boolean;
|
showConfirmTransferCommunity: boolean;
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
|
viewSource: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommentNodeProps {
|
interface CommentNodeProps {
|
||||||
|
@ -46,6 +47,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
banExpires: null,
|
banExpires: null,
|
||||||
banType: BanType.Community,
|
banType: BanType.Community,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
|
viewSource: false,
|
||||||
showConfirmTransferSite: false,
|
showConfirmTransferSite: false,
|
||||||
showConfirmTransferCommunity: false,
|
showConfirmTransferCommunity: false,
|
||||||
}
|
}
|
||||||
|
@ -106,7 +108,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
{this.state.showEdit && <CommentForm node={node} edit onReplyCancel={this.handleReplyCancel} disabled={this.props.locked} />}
|
{this.state.showEdit && <CommentForm node={node} edit onReplyCancel={this.handleReplyCancel} disabled={this.props.locked} />}
|
||||||
{!this.state.showEdit && !this.state.collapsed &&
|
{!this.state.showEdit && !this.state.collapsed &&
|
||||||
<div>
|
<div>
|
||||||
<div className="md-div" dangerouslySetInnerHTML={mdToHtml(node.comment.removed ? `*${i18n.t('removed')}*` : node.comment.deleted ? `*${i18n.t('deleted')}*` : node.comment.content)} />
|
{this.state.viewSource ? <div>{this.commentUnlessRemoved}</div> :
|
||||||
|
<div className="md-div" dangerouslySetInnerHTML={mdToHtml(this.commentUnlessRemoved)} />
|
||||||
|
}
|
||||||
<ul class="list-inline mb-1 text-muted small font-weight-bold">
|
<ul class="list-inline mb-1 text-muted small font-weight-bold">
|
||||||
{UserService.Instance.user && !this.props.viewOnly &&
|
{UserService.Instance.user && !this.props.viewOnly &&
|
||||||
<>
|
<>
|
||||||
|
@ -201,6 +205,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
<li className="list-inline-item">
|
||||||
|
<span className="pointer" onClick={linkEvent(this, this.handleViewSource)}><T i18nKey="view_source">#</T></span>
|
||||||
|
</li>
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
<Link className="text-muted" to={`/post/${node.comment.post_id}/comment/${node.comment.id}`}><T i18nKey="link">#</T></Link>
|
<Link className="text-muted" to={`/post/${node.comment.post_id}/comment/${node.comment.id}`}><T i18nKey="link">#</T></Link>
|
||||||
</li>
|
</li>
|
||||||
|
@ -297,6 +304,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
(this.props.node.comment.creator_id != UserService.Instance.user.id) &&
|
(this.props.node.comment.creator_id != UserService.Instance.user.id) &&
|
||||||
(UserService.Instance.user.id == this.props.admins[0].id);
|
(UserService.Instance.user.id == this.props.admins[0].id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get commentUnlessRemoved(): string {
|
||||||
|
let node = this.props.node;
|
||||||
|
return node.comment.removed ? `*${i18n.t('removed')}*` : node.comment.deleted ? `*${i18n.t('deleted')}*` : node.comment.content;
|
||||||
|
}
|
||||||
|
|
||||||
handleReplyClick(i: CommentNode) {
|
handleReplyClick(i: CommentNode) {
|
||||||
i.state.showReply = true;
|
i.state.showReply = true;
|
||||||
|
@ -527,4 +539,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
i.state.collapsed = !i.state.collapsed;
|
i.state.collapsed = !i.state.collapsed;
|
||||||
i.setState(i.state);
|
i.setState(i.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleViewSource(i: CommentNode) {
|
||||||
|
i.state.viewSource = !i.state.viewSource;
|
||||||
|
i.setState(i.state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
206
ui/src/components/post-listing.tsx
vendored
206
ui/src/components/post-listing.tsx
vendored
|
@ -19,6 +19,7 @@ interface PostListingState {
|
||||||
showConfirmTransferSite: boolean;
|
showConfirmTransferSite: boolean;
|
||||||
showConfirmTransferCommunity: boolean;
|
showConfirmTransferCommunity: boolean;
|
||||||
imageExpanded: boolean;
|
imageExpanded: boolean;
|
||||||
|
viewSource: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PostListingProps {
|
interface PostListingProps {
|
||||||
|
@ -44,6 +45,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
showConfirmTransferSite: false,
|
showConfirmTransferSite: false,
|
||||||
showConfirmTransferCommunity: false,
|
showConfirmTransferCommunity: false,
|
||||||
imageExpanded: false,
|
imageExpanded: false,
|
||||||
|
viewSource: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -168,103 +170,110 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<Link className="text-muted" to={`/post/${post.id}`}><T i18nKey="number_of_comments" interpolation={{count: post.number_of_comments}}>#</T></Link>
|
<Link className="text-muted" to={`/post/${post.id}`}><T i18nKey="number_of_comments" interpolation={{count: post.number_of_comments}}>#</T></Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{UserService.Instance.user && this.props.editable &&
|
<ul class="list-inline mb-1 text-muted small font-weight-bold">
|
||||||
<ul class="list-inline mb-1 text-muted small font-weight-bold">
|
{UserService.Instance.user && this.props.editable &&
|
||||||
<li className="list-inline-item mr-2">
|
<>
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleSavePostClick)}>{post.saved ? i18n.t('unsave') : i18n.t('save')}</span>
|
<li className="list-inline-item mr-2">
|
||||||
</li>
|
<span class="pointer" onClick={linkEvent(this, this.handleSavePostClick)}>{post.saved ? i18n.t('unsave') : i18n.t('save')}</span>
|
||||||
<li className="list-inline-item mr-2">
|
</li>
|
||||||
<Link className="text-muted" to={`/create_post${this.crossPostParams}`}><T i18nKey="cross_post">#</T></Link>
|
<li className="list-inline-item mr-2">
|
||||||
</li>
|
<Link className="text-muted" to={`/create_post${this.crossPostParams}`}><T i18nKey="cross_post">#</T></Link>
|
||||||
{this.myPost &&
|
</li>
|
||||||
<>
|
{this.myPost &&
|
||||||
|
<>
|
||||||
|
<li className="list-inline-item">
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleEditClick)}><T i18nKey="edit">#</T></span>
|
||||||
|
</li>
|
||||||
|
<li className="list-inline-item mr-2">
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleDeleteClick)}>
|
||||||
|
{!post.deleted ? i18n.t('delete') : i18n.t('restore')}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{this.canMod &&
|
||||||
|
<>
|
||||||
|
<li className="list-inline-item">
|
||||||
|
{!post.removed ?
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleModRemoveShow)}><T i18nKey="remove">#</T></span> :
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleModRemoveSubmit)}><T i18nKey="restore">#</T></span>
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
<li className="list-inline-item">
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleModLock)}>{post.locked ? i18n.t('unlock') : i18n.t('lock')}</span>
|
||||||
|
</li>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{/* Mods can ban from community, and appoint as mods to community */}
|
||||||
|
{this.canMod &&
|
||||||
|
<>
|
||||||
|
{!this.isMod &&
|
||||||
|
<li className="list-inline-item">
|
||||||
|
{!post.banned_from_community ?
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleModBanFromCommunityShow)}><T i18nKey="ban">#</T></span> :
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleModBanFromCommunitySubmit)}><T i18nKey="unban">#</T></span>
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
{!post.banned_from_community &&
|
||||||
|
<li className="list-inline-item">
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleAddModToCommunity)}>{this.isMod ? i18n.t('remove_as_mod') : i18n.t('appoint_as_mod')}</span>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{/* Community creators and admins can transfer community to another mod */}
|
||||||
|
{(this.amCommunityCreator || this.canAdmin) && this.isMod &&
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleEditClick)}><T i18nKey="edit">#</T></span>
|
{!this.state.showConfirmTransferCommunity ?
|
||||||
</li>
|
<span class="pointer" onClick={linkEvent(this, this.handleShowConfirmTransferCommunity)}><T i18nKey="transfer_community">#</T>
|
||||||
<li className="list-inline-item mr-2">
|
</span> : <>
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleDeleteClick)}>
|
<span class="d-inline-block mr-1"><T i18nKey="are_you_sure">#</T></span>
|
||||||
{!post.deleted ? i18n.t('delete') : i18n.t('restore')}
|
<span class="pointer d-inline-block mr-1" onClick={linkEvent(this, this.handleTransferCommunity)}><T i18nKey="yes">#</T></span>
|
||||||
</span>
|
<span class="pointer d-inline-block" onClick={linkEvent(this, this.handleCancelShowConfirmTransferCommunity)}><T i18nKey="no">#</T></span>
|
||||||
</li>
|
</>
|
||||||
</>
|
|
||||||
}
|
|
||||||
{this.canMod &&
|
|
||||||
<>
|
|
||||||
<li className="list-inline-item">
|
|
||||||
{!post.removed ?
|
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleModRemoveShow)}><T i18nKey="remove">#</T></span> :
|
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleModRemoveSubmit)}><T i18nKey="restore">#</T></span>
|
|
||||||
}
|
}
|
||||||
</li>
|
</li>
|
||||||
|
}
|
||||||
|
{/* Admins can ban from all, and appoint other admins */}
|
||||||
|
{this.canAdmin &&
|
||||||
|
<>
|
||||||
|
{!this.isAdmin &&
|
||||||
|
<li className="list-inline-item">
|
||||||
|
{!post.banned ?
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleModBanShow)}><T i18nKey="ban_from_site">#</T></span> :
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleModBanSubmit)}><T i18nKey="unban_from_site">#</T></span>
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
{!post.banned &&
|
||||||
|
<li className="list-inline-item">
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleAddAdmin)}>{this.isAdmin ? i18n.t('remove_as_admin') : i18n.t('appoint_as_admin')}</span>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{/* Site Creator can transfer to another admin */}
|
||||||
|
{this.amSiteCreator && this.isAdmin &&
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleModLock)}>{post.locked ? i18n.t('unlock') : i18n.t('lock')}</span>
|
{!this.state.showConfirmTransferSite ?
|
||||||
|
<span class="pointer" onClick={linkEvent(this, this.handleShowConfirmTransferSite)}><T i18nKey="transfer_site">#</T>
|
||||||
|
</span> : <>
|
||||||
|
<span class="d-inline-block mr-1"><T i18nKey="are_you_sure">#</T></span>
|
||||||
|
<span class="pointer d-inline-block mr-1" onClick={linkEvent(this, this.handleTransferSite)}><T i18nKey="yes">#</T></span>
|
||||||
|
<span class="pointer d-inline-block" onClick={linkEvent(this, this.handleCancelShowConfirmTransferSite)}><T i18nKey="no">#</T></span>
|
||||||
|
</>
|
||||||
|
}
|
||||||
</li>
|
</li>
|
||||||
</>
|
}
|
||||||
}
|
</>
|
||||||
{/* Mods can ban from community, and appoint as mods to community */}
|
}
|
||||||
{this.canMod &&
|
{this.props.showBody && post.body &&
|
||||||
<>
|
<li className="list-inline-item">
|
||||||
{!this.isMod &&
|
<span className="pointer" onClick={linkEvent(this, this.handleViewSource)}><T i18nKey="view_source">#</T></span>
|
||||||
<li className="list-inline-item">
|
</li>
|
||||||
{!post.banned_from_community ?
|
}
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleModBanFromCommunityShow)}><T i18nKey="ban">#</T></span> :
|
</ul>
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleModBanFromCommunitySubmit)}><T i18nKey="unban">#</T></span>
|
|
||||||
}
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
{!post.banned_from_community &&
|
|
||||||
<li className="list-inline-item">
|
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleAddModToCommunity)}>{this.isMod ? i18n.t('remove_as_mod') : i18n.t('appoint_as_mod')}</span>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
{/* Community creators and admins can transfer community to another mod */}
|
|
||||||
{(this.amCommunityCreator || this.canAdmin) && this.isMod &&
|
|
||||||
<li className="list-inline-item">
|
|
||||||
{!this.state.showConfirmTransferCommunity ?
|
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleShowConfirmTransferCommunity)}><T i18nKey="transfer_community">#</T>
|
|
||||||
</span> : <>
|
|
||||||
<span class="d-inline-block mr-1"><T i18nKey="are_you_sure">#</T></span>
|
|
||||||
<span class="pointer d-inline-block mr-1" onClick={linkEvent(this, this.handleTransferCommunity)}><T i18nKey="yes">#</T></span>
|
|
||||||
<span class="pointer d-inline-block" onClick={linkEvent(this, this.handleCancelShowConfirmTransferCommunity)}><T i18nKey="no">#</T></span>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
{/* Admins can ban from all, and appoint other admins */}
|
|
||||||
{this.canAdmin &&
|
|
||||||
<>
|
|
||||||
{!this.isAdmin &&
|
|
||||||
<li className="list-inline-item">
|
|
||||||
{!post.banned ?
|
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleModBanShow)}><T i18nKey="ban_from_site">#</T></span> :
|
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleModBanSubmit)}><T i18nKey="unban_from_site">#</T></span>
|
|
||||||
}
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
{!post.banned &&
|
|
||||||
<li className="list-inline-item">
|
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleAddAdmin)}>{this.isAdmin ? i18n.t('remove_as_admin') : i18n.t('appoint_as_admin')}</span>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
{/* Site Creator can transfer to another admin */}
|
|
||||||
{this.amSiteCreator && this.isAdmin &&
|
|
||||||
<li className="list-inline-item">
|
|
||||||
{!this.state.showConfirmTransferSite ?
|
|
||||||
<span class="pointer" onClick={linkEvent(this, this.handleShowConfirmTransferSite)}><T i18nKey="transfer_site">#</T>
|
|
||||||
</span> : <>
|
|
||||||
<span class="d-inline-block mr-1"><T i18nKey="are_you_sure">#</T></span>
|
|
||||||
<span class="pointer d-inline-block mr-1" onClick={linkEvent(this, this.handleTransferSite)}><T i18nKey="yes">#</T></span>
|
|
||||||
<span class="pointer d-inline-block" onClick={linkEvent(this, this.handleCancelShowConfirmTransferSite)}><T i18nKey="no">#</T></span>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
}
|
|
||||||
{this.state.showRemoveDialog &&
|
{this.state.showRemoveDialog &&
|
||||||
<form class="form-inline" onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
|
<form class="form-inline" onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
|
||||||
<input type="text" class="form-control mr-2" placeholder={i18n.t('reason')} value={this.state.removeReason} onInput={linkEvent(this, this.handleModRemoveReasonChange)} />
|
<input type="text" class="form-control mr-2" placeholder={i18n.t('reason')} value={this.state.removeReason} onInput={linkEvent(this, this.handleModRemoveReasonChange)} />
|
||||||
|
@ -287,7 +296,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
{this.props.showBody && post.body && <div className="md-div" dangerouslySetInnerHTML={mdToHtml(post.body)} />}
|
{this.props.showBody && post.body &&
|
||||||
|
<>
|
||||||
|
{this.state.viewSource ? <div>{post.body}</div> :
|
||||||
|
<div className="md-div" dangerouslySetInnerHTML={mdToHtml(post.body)} />
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -566,5 +581,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
i.state.imageExpanded = !i.state.imageExpanded;
|
i.state.imageExpanded = !i.state.imageExpanded;
|
||||||
i.setState(i.state);
|
i.setState(i.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleViewSource(i: PostListing) {
|
||||||
|
i.state.viewSource = !i.state.viewSource;
|
||||||
|
i.setState(i.state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
ui/src/translations/en.ts
vendored
1
ui/src/translations/en.ts
vendored
|
@ -29,6 +29,7 @@ export const en = {
|
||||||
preview: 'Preview',
|
preview: 'Preview',
|
||||||
upload_image: 'upload image',
|
upload_image: 'upload image',
|
||||||
formatting_help: 'formatting help',
|
formatting_help: 'formatting help',
|
||||||
|
view_source: 'view source',
|
||||||
unlock: 'unlock',
|
unlock: 'unlock',
|
||||||
lock: 'lock',
|
lock: 'lock',
|
||||||
link: 'link',
|
link: 'link',
|
||||||
|
|
Loading…
Reference in a new issue