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 { MomentTime } from './moment-time'; import { PostForm } from './post-form'; import { mdToHtml, canMod, isMod, isImage } from '../utils'; import { i18n } from '../i18next'; import { T } from 'inferno-i18next'; interface PostListingState { showEdit: boolean; showRemoveDialog: boolean; removeReason: string; imageExpanded: boolean; } interface PostListingProps { post: Post; editable?: boolean; showCommunity?: boolean; showBody?: boolean; viewOnly?: boolean; moderators?: Array; admins?: Array; } export class PostListing extends Component { private emptyState: PostListingState = { showEdit: false, showRemoveDialog: false, removeReason: null, imageExpanded: false } constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; this.handlePostLike = this.handlePostLike.bind(this); this.handlePostDisLike = this.handlePostDisLike.bind(this); this.handleEditPost = this.handleEditPost.bind(this); this.handleEditCancel = this.handleEditCancel.bind(this); } render() { return (
{!this.state.showEdit ? this.listing() : }
) } listing() { let post = this.props.post; return (
{post.score}
{post.url && isImage(post.url) && }
{post.url ? {post.name} : {post.name} }
{post.url && {(new URL(post.url)).hostname} } { post.url && isImage(post.url) && <> { !this.state.imageExpanded ? [+] : [-]
} } {post.removed && # } {post.deleted && # } {post.locked && # } {post.nsfw && # }
  • by {post.creator_name} {this.isMod && # } {this.isAdmin && # } {this.props.showCommunity && to {post.community_name} }
  • ( +{post.upvotes} | -{post.downvotes} )
  • #
{UserService.Instance.user && this.props.editable &&
  • {post.saved ? i18n.t('unsave') : i18n.t('save')}
  • #
  • {this.myPost && <>
  • #
  • {!post.deleted ? i18n.t('delete') : i18n.t('restore')}
  • } {this.canMod &&
  • {!this.props.post.removed ? # : # }
  • {this.props.post.locked ? i18n.t('unlock') : i18n.t('lock')}
  • }
} {this.state.showRemoveDialog &&
} {this.props.showBody && this.props.post.body &&
}
) } private get myPost(): boolean { return UserService.Instance.user && this.props.post.creator_id == UserService.Instance.user.id; } get isMod(): boolean { return this.props.moderators && isMod(this.props.moderators.map(m => m.user_id), this.props.post.creator_id); } get isAdmin(): boolean { return this.props.admins && isMod(this.props.admins.map(a => a.id), this.props.post.creator_id); } get canMod(): boolean { if (this.props.editable) { let adminsThenMods = this.props.admins.map(a => a.id) .concat(this.props.moderators.map(m => m.user_id)); return canMod(UserService.Instance.user, adminsThenMods, this.props.post.creator_id); } else return false; } handlePostLike(i: PostListing) { let form: CreatePostLikeForm = { post_id: i.props.post.id, score: (i.props.post.my_vote == 1) ? 0 : 1 }; WebSocketService.Instance.likePost(form); } handlePostDisLike(i: PostListing) { let form: CreatePostLikeForm = { post_id: i.props.post.id, score: (i.props.post.my_vote == -1) ? 0 : -1 }; WebSocketService.Instance.likePost(form); } handleEditClick(i: PostListing) { i.state.showEdit = true; i.setState(i.state); } handleEditCancel() { this.state.showEdit = false; this.setState(this.state); } // The actual editing is done in the recieve for post handleEditPost() { this.state.showEdit = false; this.setState(this.state); } handleDeleteClick(i: PostListing) { let deleteForm: PostFormI = { body: i.props.post.body, community_id: i.props.post.community_id, name: i.props.post.name, url: i.props.post.url, edit_id: i.props.post.id, creator_id: i.props.post.creator_id, deleted: !i.props.post.deleted, nsfw: i.props.post.nsfw, auth: null }; WebSocketService.Instance.editPost(deleteForm); } handleSavePostClick(i: PostListing) { let saved = (i.props.post.saved == undefined) ? true : !i.props.post.saved; let form: SavePostForm = { post_id: i.props.post.id, save: saved }; WebSocketService.Instance.savePost(form); } get crossPostParams(): string { let params = `?name=${this.props.post.name}`; if (this.props.post.url) { params += `&url=${this.props.post.url}`; } if (this.props.post.body) { params += `&body=${this.props.post.body}`; } return params; } handleModRemoveShow(i: PostListing) { i.state.showRemoveDialog = true; i.setState(i.state); } handleModRemoveReasonChange(i: PostListing, event: any) { i.state.removeReason = event.target.value; i.setState(i.state); } handleModRemoveSubmit(i: PostListing) { event.preventDefault(); let form: PostFormI = { name: i.props.post.name, community_id: i.props.post.community_id, edit_id: i.props.post.id, creator_id: i.props.post.creator_id, removed: !i.props.post.removed, reason: i.state.removeReason, nsfw: i.props.post.nsfw, auth: null, }; WebSocketService.Instance.editPost(form); i.state.showRemoveDialog = false; i.setState(i.state); } handleModLock(i: PostListing) { let form: PostFormI = { name: i.props.post.name, community_id: i.props.post.community_id, edit_id: i.props.post.id, creator_id: i.props.post.creator_id, nsfw: i.props.post.nsfw, locked: !i.props.post.locked, auth: null, }; WebSocketService.Instance.editPost(form); } handleImageExpandClick(i: PostListing) { i.state.imageExpanded = !i.state.imageExpanded; i.setState(i.state); } }