import React from 'react'; //jshint ignore:line
import CategorySelect from 'misago/components/category-select'; //jshint ignore:line
import Editor from 'misago/components/editor'; //jshint ignore:line
import Form from 'misago/components/form';
import Container from './utils/container'; //jshint ignore:line
import Loader from './utils/loader'; //jshint ignore:line
import Message from './utils/message'; //jshint ignore:line
import Options from './utils/options'; //jshint ignore:line
import * as attachments from './utils/attachments'; //jshint ignore:line
import { getPostValidators, getTitleValidators } from './utils/validators';
import ajax from 'misago/services/ajax';
import posting from 'misago/services/posting'; //jshint ignore:line
import snackbar from 'misago/services/snackbar';
export default class extends Form {
constructor(props) {
super(props);
this.state = {
isReady: false,
isLoading: false,
isErrored: false,
showOptions: false,
categoryOptions: null,
title: '',
category: props.category || null,
categories: [],
post: '',
attachments: [],
close: false,
hide: false,
pin: 0,
validators: {
title: getTitleValidators(),
post: getPostValidators()
},
errors: {}
};
}
componentDidMount() {
ajax.get(this.props.config).then(this.loadSuccess, this.loadError);
}
/* jshint ignore:start */
loadSuccess = (data) => {
let category = null;
let showOptions = false;
let categoryOptions = null;
// hydrate categories, extract posting options
const categories = data.map((item) => {
// pick first category that allows posting and if it may, override it with initial one
if (item.post !== false && (!category || item.id == this.state.category)) {
category = item.id;
categoryOptions = item.post;
}
if (item.post && (item.post.close || item.post.hide || item.post.pin)) {
showOptions = true;
}
return Object.assign(item, {
disabled: item.post === false,
label: item.name,
value: item.id
});
});
this.setState({
isReady: true,
showOptions,
categories,
category,
categoryOptions
});
};
loadError = (rejection) => {
this.setState({
isErrored: rejection.detail
});
};
onCancel = () => {
const cancel = confirm(gettext("Are you sure you want to discard thread?"));
if (cancel) {
posting.close();
}
};
onTitleChange = (event) => {
this.changeValue('title', event.target.value);
};
onCategoryChange = (event) => {
const category = this.state.categories.find((item) => {
return event.target.value == item.value;
});
// if selected pin is greater than allowed, reduce it
let pin = this.state.pin;
if (category.post.pin && category.post.pin < pin) {
pin = category.post.pin;
}
this.setState({
category: category.id,
categoryOptions: category.post,
pin
});
};
onPostChange = (event) => {
this.changeValue('post', event.target.value);
};
onAttachmentsChange = (attachments) => {
this.setState({
attachments
});
};
onClose = () => {
this.changeValue('close', true);
};
onOpen = () => {
this.changeValue('close', false);
};
onPinGlobally = () => {
this.changeValue('pin', 2);
};
onPinLocally = () => {
this.changeValue('pin', 1);
};
onUnpin = () => {
this.changeValue('pin', 0);
};
onHide = () => {
this.changeValue('hide', true);
};
onUnhide = () => {
this.changeValue('hide', false);
};
/* jshint ignore:end */
clean() {
if (!this.state.title.trim().length) {
snackbar.error(gettext("You have to enter thread title."));
return false;
}
if (!this.state.post.trim().length) {
snackbar.error(gettext("You have to enter a message."));
return false;
}
const errors = this.validate();
if (errors.title) {
snackbar.error(errors.title[0]);
return false;
}
if (errors.post) {
snackbar.error(errors.post[0]);
return false;
}
return true;
}
send() {
return ajax.post(this.props.submit, {
title: this.state.title,
category: this.state.category,
post: this.state.post,
attachments: attachments.clean(this.state.attachments),
close: this.state.close,
hide: this.state.hide,
pin: this.state.pin
});
}
handleSuccess(success) {
snackbar.success(gettext("Your thread has been posted."));
window.location = success.url;
// keep form loading
this.setState({
'isLoading': true
});
}
handleError(rejection) {
if (rejection.status === 400) {
const errors = [].concat(
rejection.non_field_errors || [],
rejection.category || [],
rejection.title || [],
rejection.post || []
);
snackbar.error(errors[0]);
} else {
snackbar.apiError(rejection);
}
}
render() {
/* jshint ignore:start */
if (this.state.isErrored) {
return (
);
}
if (!this.state.isReady) {
return (
);
}
let columns = 0;
if (this.state.categoryOptions.close) columns += 1;
if (this.state.categoryOptions.hide) columns += 1;
if (this.state.categoryOptions.pin) columns += 1;
let titleStyle = null;
if (columns === 1) {
titleStyle = 'col-sm-6';
} else {
titleStyle = 'col-sm-8';
}
if (columns === 3) {
titleStyle += ' col-md-6'
} else if (columns) {
titleStyle += ' col-md-7'
} else {
titleStyle += ' col-md-9'
}
return (
);
/* jshint ignore:end */
}
}