import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { get, find, orderBy } from 'lodash'; import marked from 'marked'; import { DateTime } from 'luxon'; import { inject, observer } from 'mobx-react'; import { CharacterService, ThreadService } from '../../services'; import { Editor, Portrait, ScrollToTop } from '../../components'; import { ReplyModel, ThreadModel } from '../../model'; import { UserStore } from '../../stores/user-store'; import { Oauth } from '../../util'; import './thread.scss'; interface Props extends RouteComponentProps { userStore: UserStore; } interface State { editingReply?: ReplyModel; quotedReply?: ReplyModel; showEditor: boolean; thread?: ThreadModel; } @inject('userStore') @observer export class Thread extends React.Component { constructor(props: Props) { super(props); this.state = { showEditor: false, }; } componentDidMount() { this.getReplies(); } private async getReplies() { const thread = await ThreadService.getThread(this.props.match.params['threadId']); thread.replies = orderBy(thread.replies, ['inserted_at']); this.setState({ thread }); } private onReplyClick() { this.props.userStore.user ? this.setState({ showEditor: true }) : Oauth.openOuathWindow(); } private onQuoteClick(reply: ReplyModel) { this.props.userStore.user ? this.setState({ showEditor: true, quotedReply: reply, }) : Oauth.openOuathWindow(); } private onEditClick(reply: ReplyModel) { this.setState({ editingReply: reply, showEditor: true, }); } private onEditorClose(cancel: boolean) { this.setState({ showEditor: false, quotedReply: undefined, editingReply: undefined, }); if (!cancel) { this.getReplies(); } } private navigateForumIndex() { this.props.history.push(`/f/${this.state.thread!.category_id}`); } private getTimeFormat(dateTime: string) { return DateTime.fromISO(dateTime).toLocaleString({ year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: '2-digit', timeZoneName: 'short', }); } private renderQuotedReply(reply: ReplyModel) { const quotedReply = find(this.state.thread!.replies, { id: reply.quote_id }); return (quotedReply &&
Q u o t e:
); } renderUserInfo(reply: ReplyModel) { const { battletag, character_avatar, character_class, character_guild, character_name, character_realm, permissions } = reply.user; return (
{character_name || battletag}
{character_class &&
{character_class}
} {character_guild &&
Guild: {character_guild}
} {character_realm &&
Realm: {character_realm}
} {permissions === 'admin' &&
Admin Poster
}
); } renderEditbutton(reply: ReplyModel): any { if (get(this.props, 'userStore.user.id') === reply.user_id) { return this.onEditClick(reply)}>Edit; } } renderReplies(): any { return this.state.thread!.replies.map((reply, index) => { const replyDark = index % 2 === 0 ? 'reply--dark' : ''; const bluePost = reply.user.permissions === 'admin' ? 'blue-post' : ''; return (
{this.renderUserInfo(reply)}
{`${index + 1}. `}{index > 0 && 'Re: '}{this.state.thread!.title} | {this.getTimeFormat(reply.inserted_at)}
{this.renderEditbutton(reply)} this.onQuoteClick(reply)}/> this.onReplyClick()}/>
{this.renderQuotedReply(reply)}
{reply.edited && [ post edited by {reply.user.character_name || reply.user.battletag} ]}
); }); } render() { if (!this.state.thread) { return
; } const replies = get(this.state, 'thread.replies'); return ( {this.state.showEditor && this.onEditorClose(cancel)} quotedReply={this.state.quotedReply} editingReply={this.state.editingReply} /> }
Topic: | {this.getTimeFormat(this.state.thread!.inserted_at)}
this.navigateForumIndex()} style={{ cursor: 'pointer' }} />
{replies && this.renderReplies()}
this.navigateForumIndex()} style={{ cursor: 'pointer', float: 'right' }} />
); } }