Adding view source button for posts and comments.

- Fixes #271
pull/283/head
Dessalines 2019-09-08 11:00:08 -07:00
parent ae40c2b08d
commit a8da6d37c2
3 changed files with 132 additions and 94 deletions

View File

@ -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>
@ -298,6 +305,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
(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;
i.setState(i.state); i.setState(i.state);
@ -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);
}
} }

View File

@ -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,8 +170,9 @@ 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"> <li className="list-inline-item mr-2">
<span class="pointer" onClick={linkEvent(this, this.handleSavePostClick)}>{post.saved ? i18n.t('unsave') : i18n.t('save')}</span> <span class="pointer" onClick={linkEvent(this, this.handleSavePostClick)}>{post.saved ? i18n.t('unsave') : i18n.t('save')}</span>
</li> </li>
@ -263,8 +266,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
} }
</li> </li>
} }
</ul> </>
} }
{this.props.showBody && post.body &&
<li className="list-inline-item">
<span className="pointer" onClick={linkEvent(this, this.handleViewSource)}><T i18nKey="view_source">#</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);
}
} }

View File

@ -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',