diff options
Diffstat (limited to 'ui/src/components/post-listing.tsx')
-rw-r--r-- | ui/src/components/post-listing.tsx | 245 |
1 files changed, 237 insertions, 8 deletions
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx index 4a3b744a..ccd3ce45 100644 --- a/ui/src/components/post-listing.tsx +++ b/ui/src/components/post-listing.tsx @@ -1,10 +1,10 @@ import { Component, linkEvent } from 'inferno'; import { Link } from 'inferno-router'; import { WebSocketService, UserService } from '../services'; -import { Post, CreatePostLikeForm, PostForm as PostFormI, SavePostForm, CommunityUser, UserView } from '../interfaces'; +import { Post, CreatePostLikeForm, PostForm as PostFormI, SavePostForm, CommunityUser, UserView, BanType, BanFromCommunityForm, BanUserForm, AddModToCommunityForm, AddAdminForm, TransferSiteForm, TransferCommunityForm } from '../interfaces'; import { MomentTime } from './moment-time'; import { PostForm } from './post-form'; -import { mdToHtml, canMod, isMod, isImage } from '../utils'; +import { mdToHtml, canMod, isMod, isImage, getUnixTime } from '../utils'; import { i18n } from '../i18next'; import { T } from 'inferno-i18next'; @@ -12,6 +12,12 @@ interface PostListingState { showEdit: boolean; showRemoveDialog: boolean; removeReason: string; + showBanDialog: boolean; + banReason: string; + banExpires: string; + banType: BanType; + showConfirmTransferSite: boolean; + showConfirmTransferCommunity: boolean; imageExpanded: boolean; } @@ -31,7 +37,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> { showEdit: false, showRemoveDialog: false, removeReason: null, - imageExpanded: false + showBanDialog: false, + banReason: null, + banExpires: null, + banType: BanType.Community, + showConfirmTransferSite: false, + showConfirmTransferCommunity: false, + imageExpanded: false, } constructor(props: any, context: any) { @@ -126,6 +138,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> { {this.isAdmin && <span className="mx-1 badge badge-light"><T i18nKey="admin">#</T></span> } + {(post.banned_from_community || post.banned) && + <span className="mx-1 badge badge-danger"><T i18nKey="banned">#</T></span> + } {this.props.showCommunity && <span> <span> {i18n.t('to')} </span> @@ -169,17 +184,79 @@ export class PostListing extends Component<PostListingProps, PostListingState> { </> } {this.canMod && - <span> + <> <li className="list-inline-item"> - {!this.props.post.removed ? + {!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)}>{this.props.post.locked ? i18n.t('unlock') : i18n.t('lock')}</span> + <span class="pointer" onClick={linkEvent(this, this.handleModLock)}>{post.locked ? i18n.t('unlock') : i18n.t('lock')}</span> </li> - </span> + </> + } + {/* 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"> + {!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> } @@ -189,7 +266,23 @@ export class PostListing extends Component<PostListingProps, PostListingState> { <button type="submit" class="btn btn-secondary"><T i18nKey="remove_post">#</T></button> </form> } - {this.props.showBody && this.props.post.body && <div className="md-div" dangerouslySetInnerHTML={mdToHtml(post.body)} />} + {this.state.showBanDialog && + <form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}> + <div class="form-group row"> + <label class="col-form-label"><T i18nKey="reason">#</T></label> + <input type="text" class="form-control mr-2" placeholder={i18n.t('reason')} value={this.state.banReason} onInput={linkEvent(this, this.handleModBanReasonChange)} /> + </div> + {/* TODO hold off on expires until later */} + {/* <div class="form-group row"> */} + {/* <label class="col-form-label">Expires</label> */} + {/* <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */} + {/* </div> */} + <div class="form-group row"> + <button type="submit" class="btn btn-secondary">{i18n.t('ban')} {post.creator_name}</button> + </div> + </form> + } + {this.props.showBody && post.body && <div className="md-div" dangerouslySetInnerHTML={mdToHtml(post.body)} />} </div> </div> ) @@ -218,6 +311,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> { } else return false; } + get canAdmin(): boolean { + return this.props.admins && canMod(UserService.Instance.user, this.props.admins.map(a => a.id), this.props.post.creator_id); + } + + get amCommunityCreator(): boolean { + return this.props.moderators && + UserService.Instance.user && + (this.props.post.creator_id != UserService.Instance.user.id) && + (UserService.Instance.user.id == this.props.moderators[0].user_id); + } + + get amSiteCreator(): boolean { + return this.props.admins && + UserService.Instance.user && + (this.props.post.creator_id != UserService.Instance.user.id) && + (UserService.Instance.user.id == this.props.admins[0].id); + } + handlePostLike(i: PostListing) { let form: CreatePostLikeForm = { @@ -328,6 +439,124 @@ export class PostListing extends Component<PostListingProps, PostListingState> { WebSocketService.Instance.editPost(form); } + handleModBanFromCommunityShow(i: PostListing) { + i.state.showBanDialog = true; + i.state.banType = BanType.Community; + i.setState(i.state); + } + + handleModBanShow(i: PostListing) { + i.state.showBanDialog = true; + i.state.banType = BanType.Site; + i.setState(i.state); + } + + handleModBanReasonChange(i: PostListing, event: any) { + i.state.banReason = event.target.value; + i.setState(i.state); + } + + handleModBanExpiresChange(i: PostListing, event: any) { + i.state.banExpires = event.target.value; + i.setState(i.state); + } + + handleModBanFromCommunitySubmit(i: PostListing) { + i.state.banType = BanType.Community; + i.setState(i.state); + i.handleModBanBothSubmit(i); + } + + handleModBanSubmit(i: PostListing) { + i.state.banType = BanType.Site; + i.setState(i.state); + i.handleModBanBothSubmit(i); + } + + handleModBanBothSubmit(i: PostListing) { + event.preventDefault(); + + if (i.state.banType == BanType.Community) { + let form: BanFromCommunityForm = { + user_id: i.props.post.creator_id, + community_id: i.props.post.community_id, + ban: !i.props.post.banned_from_community, + reason: i.state.banReason, + expires: getUnixTime(i.state.banExpires), + }; + WebSocketService.Instance.banFromCommunity(form); + } else { + let form: BanUserForm = { + user_id: i.props.post.creator_id, + ban: !i.props.post.banned, + reason: i.state.banReason, + expires: getUnixTime(i.state.banExpires), + }; + WebSocketService.Instance.banUser(form); + } + + i.state.showBanDialog = false; + i.setState(i.state); + } + + handleAddModToCommunity(i: PostListing) { + let form: AddModToCommunityForm = { + user_id: i.props.post.creator_id, + community_id: i.props.post.community_id, + added: !i.isMod, + }; + WebSocketService.Instance.addModToCommunity(form); + i.setState(i.state); + } + + handleAddAdmin(i: PostListing) { + let form: AddAdminForm = { + user_id: i.props.post.creator_id, + added: !i.isAdmin, + }; + WebSocketService.Instance.addAdmin(form); + i.setState(i.state); + } + + handleShowConfirmTransferCommunity(i: PostListing) { + i.state.showConfirmTransferCommunity = true; + i.setState(i.state); + } + + handleCancelShowConfirmTransferCommunity(i: PostListing) { + i.state.showConfirmTransferCommunity = false; + i.setState(i.state); + } + + handleTransferCommunity(i: PostListing) { + let form: TransferCommunityForm = { + community_id: i.props.post.community_id, + user_id: i.props.post.creator_id, + }; + WebSocketService.Instance.transferCommunity(form); + i.state.showConfirmTransferCommunity = false; + i.setState(i.state); + } + + handleShowConfirmTransferSite(i: PostListing) { + i.state.showConfirmTransferSite = true; + i.setState(i.state); + } + + handleCancelShowConfirmTransferSite(i: PostListing) { + i.state.showConfirmTransferSite = false; + i.setState(i.state); + } + + handleTransferSite(i: PostListing) { + let form: TransferSiteForm = { + user_id: i.props.post.creator_id, + }; + WebSocketService.Instance.transferSite(form); + i.state.showConfirmTransferSite = false; + i.setState(i.state); + } + handleImageExpandClick(i: PostListing) { i.state.imageExpanded = !i.state.imageExpanded; i.setState(i.state); |