1 import { Component, linkEvent } from "inferno";
2 import { Prompt } from "inferno-router";
9 } from "lemmy-js-client";
10 import { Subscription } from "rxjs";
11 import { i18n } from "../../i18next";
12 import { WebSocketService } from "../../services";
15 capitalizeFirstLetter,
23 import { Icon, Spinner } from "../common/icon";
24 import { ImageUploadForm } from "../common/image-upload-form";
25 import { MarkdownTextArea } from "../common/markdown-textarea";
27 interface CommunityFormProps {
28 community_view?: CommunityView; // If a community is given, that means this is an edit
30 onCreate?(community: CommunityView): any;
31 onEdit?(community: CommunityView): any;
35 interface CommunityFormState {
36 communityForm: CreateCommunity;
40 export class CommunityForm extends Component<
44 private id = `community-form-${randomStr()}`;
45 private subscription: Subscription;
47 private emptyState: CommunityFormState = {
54 auth: authField(false),
59 constructor(props: any, context: any) {
60 super(props, context);
62 this.state = this.emptyState;
64 this.handleCommunityDescriptionChange =
65 this.handleCommunityDescriptionChange.bind(this);
67 this.handleIconUpload = this.handleIconUpload.bind(this);
68 this.handleIconRemove = this.handleIconRemove.bind(this);
70 this.handleBannerUpload = this.handleBannerUpload.bind(this);
71 this.handleBannerRemove = this.handleBannerRemove.bind(this);
73 let cv = this.props.community_view;
75 this.state.communityForm = {
76 name: cv.community.name,
77 title: cv.community.title,
78 description: cv.community.description,
79 nsfw: cv.community.nsfw,
80 icon: cv.community.icon,
81 banner: cv.community.banner,
86 this.parseMessage = this.parseMessage.bind(this);
87 this.subscription = wsSubscribe(this.parseMessage);
90 // TODO this should be checked out
91 componentDidUpdate() {
93 !this.state.loading &&
94 (this.state.communityForm.name ||
95 this.state.communityForm.title ||
96 this.state.communityForm.description)
98 window.onbeforeunload = () => true;
100 window.onbeforeunload = undefined;
104 componentWillUnmount() {
105 this.subscription.unsubscribe();
106 window.onbeforeunload = null;
114 !this.state.loading &&
115 (this.state.communityForm.name ||
116 this.state.communityForm.title ||
117 this.state.communityForm.description)
119 message={i18n.t("block_leaving")}
121 <form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
122 {!this.props.community_view && (
123 <div class="form-group row">
124 <label class="col-12 col-form-label" htmlFor="community-name">
127 class="pointer unselectable ml-2 text-muted"
128 data-tippy-content={i18n.t("name_explain")}
130 <Icon icon="help-circle" classes="icon-inline" />
138 value={this.state.communityForm.name}
139 onInput={linkEvent(this, this.handleCommunityNameChange)}
143 title={i18n.t("community_reqs")}
148 <div class="form-group row">
149 <label class="col-12 col-form-label" htmlFor="community-title">
150 {i18n.t("display_name")}
152 class="pointer unselectable ml-2 text-muted"
153 data-tippy-content={i18n.t("display_name_explain")}
155 <Icon icon="help-circle" classes="icon-inline" />
162 value={this.state.communityForm.title}
163 onInput={linkEvent(this, this.handleCommunityTitleChange)}
171 <div class="form-group">
172 <label>{i18n.t("icon")}</label>
174 uploadTitle={i18n.t("upload_icon")}
175 imageSrc={this.state.communityForm.icon}
176 onUpload={this.handleIconUpload}
177 onRemove={this.handleIconRemove}
181 <div class="form-group">
182 <label>{i18n.t("banner")}</label>
184 uploadTitle={i18n.t("upload_banner")}
185 imageSrc={this.state.communityForm.banner}
186 onUpload={this.handleBannerUpload}
187 onRemove={this.handleBannerRemove}
190 <div class="form-group row">
191 <label class="col-12 col-form-label" htmlFor={this.id}>
196 initialContent={this.state.communityForm.description}
197 onContentChange={this.handleCommunityDescriptionChange}
202 {this.props.enableNsfw && (
203 <div class="form-group row">
205 <div class="form-check">
207 class="form-check-input"
210 checked={this.state.communityForm.nsfw}
211 onChange={linkEvent(this, this.handleCommunityNsfwChange)}
213 <label class="form-check-label" htmlFor="community-nsfw">
220 <div class="form-group row">
224 class="btn btn-secondary mr-2"
225 disabled={this.state.loading}
227 {this.state.loading ? (
229 ) : this.props.community_view ? (
230 capitalizeFirstLetter(i18n.t("save"))
232 capitalizeFirstLetter(i18n.t("create"))
235 {this.props.community_view && (
238 class="btn btn-secondary"
239 onClick={linkEvent(this, this.handleCancel)}
251 handleCreateCommunitySubmit(i: CommunityForm, event: any) {
252 event.preventDefault();
253 i.state.loading = true;
254 if (i.props.community_view) {
255 let form: EditCommunity = {
256 ...i.state.communityForm,
257 community_id: i.props.community_view.community.id,
259 WebSocketService.Instance.send(wsClient.editCommunity(form));
261 WebSocketService.Instance.send(
262 wsClient.createCommunity(i.state.communityForm)
268 handleCommunityNameChange(i: CommunityForm, event: any) {
269 i.state.communityForm.name = event.target.value;
273 handleCommunityTitleChange(i: CommunityForm, event: any) {
274 i.state.communityForm.title = event.target.value;
278 handleCommunityDescriptionChange(val: string) {
279 this.state.communityForm.description = val;
280 this.setState(this.state);
283 handleCommunityNsfwChange(i: CommunityForm, event: any) {
284 i.state.communityForm.nsfw = event.target.checked;
288 handleCancel(i: CommunityForm) {
292 handleIconUpload(url: string) {
293 this.state.communityForm.icon = url;
294 this.setState(this.state);
298 this.state.communityForm.icon = "";
299 this.setState(this.state);
302 handleBannerUpload(url: string) {
303 this.state.communityForm.banner = url;
304 this.setState(this.state);
307 handleBannerRemove() {
308 this.state.communityForm.banner = "";
309 this.setState(this.state);
312 parseMessage(msg: any) {
313 let op = wsUserOp(msg);
316 toast(i18n.t(msg.error), "danger");
317 this.state.loading = false;
318 this.setState(this.state);
320 } else if (op == UserOperation.CreateCommunity) {
321 let data = wsJsonToRes<CommunityResponse>(msg).data;
322 this.state.loading = false;
323 this.props.onCreate(data.community_view);
324 } else if (op == UserOperation.EditCommunity) {
325 let data = wsJsonToRes<CommunityResponse>(msg).data;
326 this.state.loading = false;
327 this.props.onEdit(data.community_view);