2019-04-04 22:29:14 +00:00
import { Component , linkEvent } from 'inferno' ;
import { Subscription } from "rxjs" ;
import { retryWhen , delay , take } from 'rxjs/operators' ;
import { CommunityForm as CommunityFormI , UserOperation , Category , ListCategoriesResponse , CommunityResponse } from '../interfaces' ;
2019-04-08 05:19:02 +00:00
import { WebSocketService } from '../services' ;
2019-04-04 22:29:14 +00:00
import { msgOp } from '../utils' ;
2019-04-08 21:46:09 +00:00
import * as autosize from 'autosize' ;
2019-04-04 22:29:14 +00:00
import { Community } from '../interfaces' ;
interface CommunityFormProps {
community? : Community ; // If a community is given, that means this is an edit
2019-04-08 05:19:02 +00:00
onCancel ? ( ) : any ;
2019-04-25 21:52:18 +00:00
onCreate ? ( community : Community ) : any ;
2019-04-08 05:19:02 +00:00
onEdit ? ( community : Community ) : any ;
2019-04-04 22:29:14 +00:00
}
interface CommunityFormState {
communityForm : CommunityFormI ;
categories : Array < Category > ;
2019-04-08 21:46:09 +00:00
loading : boolean ;
2019-04-04 22:29:14 +00:00
}
export class CommunityForm extends Component < CommunityFormProps , CommunityFormState > {
private subscription : Subscription ;
private emptyState : CommunityFormState = {
communityForm : {
name : null ,
title : null ,
category_id : null
} ,
2019-04-08 21:46:09 +00:00
categories : [ ] ,
loading : false
2019-04-04 22:29:14 +00:00
}
2019-04-08 05:19:02 +00:00
constructor ( props : any , context : any ) {
2019-04-04 22:29:14 +00:00
super ( props , context ) ;
this . state = this . emptyState ;
if ( this . props . community ) {
this . state . communityForm = {
name : this.props.community.name ,
title : this.props.community.title ,
category_id : this.props.community.category_id ,
description : this.props.community.description ,
edit_id : this.props.community.id ,
auth : null
}
}
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" )
) ;
WebSocketService . Instance . listCategories ( ) ;
}
2019-04-08 21:46:09 +00:00
componentDidMount() {
autosize ( document . querySelectorAll ( 'textarea' ) ) ;
}
2019-04-04 22:29:14 +00:00
componentWillUnmount() {
this . subscription . unsubscribe ( ) ;
}
render() {
return (
< form onSubmit = { linkEvent ( this , this . handleCreateCommunitySubmit ) } >
< div class = "form-group row" >
2019-04-05 02:08:21 +00:00
< label class = "col-12 col-form-label" > Name < / label >
< div class = "col-12" >
2019-04-18 15:14:45 +00:00
< input type = "text" class = "form-control" value = { this . state . communityForm . name } onInput = { linkEvent ( this , this . handleCommunityNameChange ) } required minLength = { 3 } maxLength = { 20 } pattern = "[a-z0-9_]+" title = "lowercase, underscores, and no spaces." / >
2019-04-04 22:29:14 +00:00
< / div >
< / div >
< div class = "form-group row" >
2019-04-05 02:08:21 +00:00
< label class = "col-12 col-form-label" > Title < / label >
< div class = "col-12" >
2019-04-18 15:14:45 +00:00
< input type = "text" value = { this . state . communityForm . title } onInput = { linkEvent ( this , this . handleCommunityTitleChange ) } class = "form-control" required minLength = { 3 } maxLength = { 100 } / >
2019-04-04 22:29:14 +00:00
< / div >
< / div >
< div class = "form-group row" >
2019-04-05 02:08:21 +00:00
< label class = "col-12 col-form-label" > Sidebar < / label >
< div class = "col-12" >
2019-04-08 21:46:09 +00:00
< textarea value = { this . state . communityForm . description } onInput = { linkEvent ( this , this . handleCommunityDescriptionChange ) } class = "form-control" rows = { 3 } / >
2019-04-04 22:29:14 +00:00
< / div >
< / div >
< div class = "form-group row" >
2019-04-05 02:08:21 +00:00
< label class = "col-12 col-form-label" > Category < / label >
< div class = "col-12" >
2019-04-04 22:29:14 +00:00
< select class = "form-control" value = { this . state . communityForm . category_id } onInput = { linkEvent ( this , this . handleCommunityCategoryChange ) } >
{ this . state . categories . map ( category = >
< option value = { category . id } > { category . name } < / option >
) }
< / select >
< / div >
< / div >
< div class = "form-group row" >
2019-04-05 02:08:21 +00:00
< div class = "col-12" >
2019-04-08 21:46:09 +00:00
< button type = "submit" class = "btn btn-secondary mr-2" >
{ this . state . loading ?
< svg class = "icon icon-spinner spin" > < use xlinkHref = "#icon-spinner" > < / use > < / svg > :
this . props . community ? 'Save' : 'Create' } < / button >
{ this . props . community && < button type = "button" class = "btn btn-secondary" onClick = { linkEvent ( this , this . handleCancel ) } > Cancel < / button > }
2019-04-04 22:29:14 +00:00
< / div >
< / div >
< / form >
) ;
}
2019-04-08 05:19:02 +00:00
handleCreateCommunitySubmit ( i : CommunityForm , event : any ) {
2019-04-04 22:29:14 +00:00
event . preventDefault ( ) ;
2019-04-08 21:46:09 +00:00
i . state . loading = true ;
2019-04-04 22:29:14 +00:00
if ( i . props . community ) {
WebSocketService . Instance . editCommunity ( i . state . communityForm ) ;
} else {
2019-04-29 02:05:11 +00:00
WebSocketService . Instance . createCommunity ( i . state . communityForm ) ;
2019-04-04 22:29:14 +00:00
}
2019-04-08 21:46:09 +00:00
i . setState ( i . state ) ;
2019-04-04 22:29:14 +00:00
}
2019-04-08 05:19:02 +00:00
handleCommunityNameChange ( i : CommunityForm , event : any ) {
2019-04-04 22:29:14 +00:00
i . state . communityForm . name = event . target . value ;
i . setState ( i . state ) ;
}
2019-04-08 05:19:02 +00:00
handleCommunityTitleChange ( i : CommunityForm , event : any ) {
2019-04-04 22:29:14 +00:00
i . state . communityForm . title = event . target . value ;
i . setState ( i . state ) ;
}
2019-04-08 05:19:02 +00:00
handleCommunityDescriptionChange ( i : CommunityForm , event : any ) {
2019-04-04 22:29:14 +00:00
i . state . communityForm . description = event . target . value ;
i . setState ( i . state ) ;
}
2019-04-08 05:19:02 +00:00
handleCommunityCategoryChange ( i : CommunityForm , event : any ) {
2019-04-04 22:29:14 +00:00
i . state . communityForm . category_id = Number ( event . target . value ) ;
i . setState ( i . state ) ;
}
2019-04-08 05:19:02 +00:00
handleCancel ( i : CommunityForm ) {
2019-04-05 02:08:21 +00:00
i . props . onCancel ( ) ;
}
2019-04-04 22:29:14 +00:00
parseMessage ( msg : any ) {
let op : UserOperation = msgOp ( msg ) ;
console . log ( msg ) ;
if ( msg . error ) {
alert ( msg . error ) ;
2019-04-08 21:46:09 +00:00
this . state . loading = false ;
2019-04-09 18:35:16 +00:00
this . setState ( this . state ) ;
2019-04-04 22:29:14 +00:00
return ;
} else if ( op == UserOperation . ListCategories ) {
let res : ListCategoriesResponse = msg ;
this . state . categories = res . categories ;
2019-04-18 04:07:47 +00:00
if ( ! this . props . community ) {
this . state . communityForm . category_id = res . categories [ 0 ] . id ;
}
2019-04-04 22:29:14 +00:00
this . setState ( this . state ) ;
} else if ( op == UserOperation . CreateCommunity ) {
let res : CommunityResponse = msg ;
2019-04-08 21:46:09 +00:00
this . state . loading = false ;
2019-04-25 21:52:18 +00:00
this . props . onCreate ( res . community ) ;
2019-04-21 21:38:57 +00:00
}
// TODO is this necessary?
else if ( op == UserOperation . EditCommunity ) {
2019-04-04 22:29:14 +00:00
let res : CommunityResponse = msg ;
2019-04-08 21:46:09 +00:00
this . state . loading = false ;
2019-04-04 22:29:14 +00:00
this . props . onEdit ( res . community ) ;
}
}
}