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)}
144 title={i18n.t("community_reqs")}
149 <div class="form-group row">
150 <label class="col-12 col-form-label" htmlFor="community-title">
151 {i18n.t("display_name")}
153 class="pointer unselectable ml-2 text-muted"
154 data-tippy-content={i18n.t("display_name_explain")}
156 <Icon icon="help-circle" classes="icon-inline" />
163 value={this.state.communityForm.title}
164 onInput={linkEvent(this, this.handleCommunityTitleChange)}
172 <div class="form-group">
173 <label>{i18n.t("icon")}</label>
175 uploadTitle={i18n.t("upload_icon")}
176 imageSrc={this.state.communityForm.icon}
177 onUpload={this.handleIconUpload}
178 onRemove={this.handleIconRemove}
182 <div class="form-group">
183 <label>{i18n.t("banner")}</label>
185 uploadTitle={i18n.t("upload_banner")}
186 imageSrc={this.state.communityForm.banner}
187 onUpload={this.handleBannerUpload}
188 onRemove={this.handleBannerRemove}
191 <div class="form-group row">
192 <label class="col-12 col-form-label" htmlFor={this.id}>
197 initialContent={this.state.communityForm.description}
198 onContentChange={this.handleCommunityDescriptionChange}
203 {this.props.enableNsfw && (
204 <div class="form-group row">
206 <div class="form-check">
208 class="form-check-input"
211 checked={this.state.communityForm.nsfw}
212 onChange={linkEvent(this, this.handleCommunityNsfwChange)}
214 <label class="form-check-label" htmlFor="community-nsfw">
221 <div class="form-group row">
225 class="btn btn-secondary mr-2"
226 disabled={this.state.loading}
228 {this.state.loading ? (
230 ) : this.props.community_view ? (
231 capitalizeFirstLetter(i18n.t("save"))
233 capitalizeFirstLetter(i18n.t("create"))
236 {this.props.community_view && (
239 class="btn btn-secondary"
240 onClick={linkEvent(this, this.handleCancel)}
252 handleCreateCommunitySubmit(i: CommunityForm, event: any) {
253 event.preventDefault();
254 i.state.loading = true;
255 if (i.props.community_view) {
256 let form: EditCommunity = {
257 ...i.state.communityForm,
258 community_id: i.props.community_view.community.id,
260 WebSocketService.Instance.send(wsClient.editCommunity(form));
262 WebSocketService.Instance.send(
263 wsClient.createCommunity(i.state.communityForm)
269 handleCommunityNameChange(i: CommunityForm, event: any) {
270 i.state.communityForm.name = event.target.value;
274 handleCommunityTitleChange(i: CommunityForm, event: any) {
275 i.state.communityForm.title = event.target.value;
279 handleCommunityDescriptionChange(val: string) {
280 this.state.communityForm.description = val;
281 this.setState(this.state);
284 handleCommunityNsfwChange(i: CommunityForm, event: any) {
285 i.state.communityForm.nsfw = event.target.checked;
289 handleCancel(i: CommunityForm) {
293 handleIconUpload(url: string) {
294 this.state.communityForm.icon = url;
295 this.setState(this.state);
299 this.state.communityForm.icon = "";
300 this.setState(this.state);
303 handleBannerUpload(url: string) {
304 this.state.communityForm.banner = url;
305 this.setState(this.state);
308 handleBannerRemove() {
309 this.state.communityForm.banner = "";
310 this.setState(this.state);
313 parseMessage(msg: any) {
314 let op = wsUserOp(msg);
317 toast(i18n.t(msg.error), "danger");
318 this.state.loading = false;
319 this.setState(this.state);
321 } else if (op == UserOperation.CreateCommunity) {
322 let data = wsJsonToRes<CommunityResponse>(msg).data;
323 this.state.loading = false;
324 this.props.onCreate(data.community_view);
325 } else if (op == UserOperation.EditCommunity) {
326 let data = wsJsonToRes<CommunityResponse>(msg).data;
327 this.state.loading = false;
328 this.props.onEdit(data.community_view);