diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/src/components/comment-form.tsx | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx index f3009d34..6a504592 100644 --- a/ui/src/components/comment-form.tsx +++ b/ui/src/components/comment-form.tsx @@ -1,8 +1,13 @@ import { Component, linkEvent } from 'inferno'; +import { Subscription } from 'rxjs'; +import { retryWhen, delay, take } from 'rxjs/operators'; import { Prompt } from 'inferno-router'; import { CommentNode as CommentNodeI, CommentForm as CommentFormI, + WebSocketJsonResponse, + UserOperation, + CommentResponse, } from '../interfaces'; import { capitalizeFirstLetter, @@ -11,6 +16,7 @@ import { markdownHelpUrl, toast, setupTribute, + wsJsonToRes, } from '../utils'; import { WebSocketService, UserService } from '../services'; import autosize from 'autosize'; @@ -29,12 +35,15 @@ interface CommentFormState { commentForm: CommentFormI; buttonTitle: string; previewMode: boolean; + loading: boolean; imageLoading: boolean; } export class CommentForm extends Component<CommentFormProps, CommentFormState> { - private id = `comment-form-${randomStr()}`; + private id = `comment-textarea-${randomStr()}`; + private formId = `comment-form-${randomStr()}`; private tribute: Tribute; + private subscription: Subscription; private emptyState: CommentFormState = { commentForm: { auth: null, @@ -52,6 +61,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { ? capitalizeFirstLetter(i18n.t('edit')) : capitalizeFirstLetter(i18n.t('reply')), previewMode: false, + loading: false, imageLoading: false, }; @@ -72,6 +82,14 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { this.state.commentForm.parent_id = this.props.node.comment.id; } } + + this.subscription = WebSocketService.Instance.subject + .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10)))) + .subscribe( + msg => this.parseMessage(msg), + err => console.error(err), + () => console.log('complete') + ); } componentDidMount() { @@ -85,6 +103,10 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { }); } + componentWillUnmount() { + this.subscription.unsubscribe(); + } + render() { return ( <div class="mb-3"> @@ -92,7 +114,10 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { when={this.state.commentForm.content} message={i18n.t('block_leaving')} /> - <form onSubmit={linkEvent(this, this.handleCommentSubmit)}> + <form + id={this.formId} + onSubmit={linkEvent(this, this.handleCommentSubmit)} + > <div class="form-group row"> <div className={`col-sm-12`}> <textarea @@ -123,7 +148,13 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { class="btn btn-sm btn-secondary mr-2" disabled={this.props.disabled} > - {this.state.buttonTitle} + {this.state.loading ? ( + <svg class="icon icon-spinner spin"> + <use xlinkHref="#icon-spinner"></use> + </svg> + ) : ( + <span>{this.state.buttonTitle}</span> + )} </button> {this.state.commentForm.content && ( <button @@ -185,6 +216,19 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { ); } + handleFinished() { + this.state.previewMode = false; + this.state.loading = false; + this.state.commentForm.content = ''; + let form: any = document.getElementById(this.formId); + form.reset(); + if (this.props.node) { + this.props.onReplyCancel(); + } + autosize.update(document.querySelector('textarea')); + this.setState(this.state); + } + handleCommentSubmit(i: CommentForm, event: any) { event.preventDefault(); if (i.props.edit) { @@ -193,15 +237,8 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { WebSocketService.Instance.createComment(i.state.commentForm); } - i.state.previewMode = false; - i.state.commentForm.content = undefined; - event.target.reset(); + i.state.loading = true; i.setState(i.state); - if (i.props.node) { - i.props.onReplyCancel(); - } - - autosize.update(document.querySelector('textarea')); } handleCommentContentChange(i: CommentForm, event: any) { @@ -256,7 +293,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { i.state.commentForm.content = content; i.state.imageLoading = false; i.setState(i.state); - var textarea: any = document.getElementById(i.id); + let textarea: any = document.getElementById(i.id); autosize.update(textarea); }) .catch(error => { @@ -265,4 +302,23 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { toast(error, 'danger'); }); } + + parseMessage(msg: WebSocketJsonResponse) { + let res = wsJsonToRes(msg); + + // Only do the showing and hiding if logged in + if (UserService.Instance.user) { + if (res.op == UserOperation.CreateComment) { + let data = res.data as CommentResponse; + if (data.comment.creator_id == UserService.Instance.user.id) { + this.handleFinished(); + } + } else if (res.op == UserOperation.EditComment) { + let data = res.data as CommentResponse; + if (data.comment.creator_id == UserService.Instance.user.id) { + this.handleFinished(); + } + } + } + } } |