1 import { Component, linkEvent } from "inferno";
2 import { Prompt } from "inferno-router";
3 import { Subscription } from "rxjs";
10 } from "lemmy-js-client";
11 import { WebSocketService } from "../services";
14 capitalizeFirstLetter,
22 import { i18n } from "../i18next";
24 import { MarkdownTextArea } from "./markdown-textarea";
25 import { ImageUploadForm } from "./image-upload-form";
26 import { Icon, Spinner } from "./icon";
28 interface CommunityFormProps {
29 community_view?: CommunityView; // If a community is given, that means this is an edit
31 onCreate?(community: CommunityView): any;
32 onEdit?(community: CommunityView): any;
36 interface CommunityFormState {
37 communityForm: CreateCommunity;
41 export class CommunityForm extends Component<
45 private id = `community-form-${randomStr()}`;
46 private subscription: Subscription;
48 private emptyState: CommunityFormState = {
55 auth: authField(false),
60 constructor(props: any, context: any) {
61 super(props, context);
63 this.state = this.emptyState;
65 this.handleCommunityDescriptionChange = this.handleCommunityDescriptionChange.bind(
69 this.handleIconUpload = this.handleIconUpload.bind(this);
70 this.handleIconRemove = this.handleIconRemove.bind(this);
72 this.handleBannerUpload = this.handleBannerUpload.bind(this);
73 this.handleBannerRemove = this.handleBannerRemove.bind(this);
75 let cv = this.props.community_view;
77 this.state.communityForm = {
78 name: cv.community.name,
79 title: cv.community.title,
80 description: cv.community.description,
81 nsfw: cv.community.nsfw,
82 icon: cv.community.icon,
83 banner: cv.community.banner,
88 this.parseMessage = this.parseMessage.bind(this);
89 this.subscription = wsSubscribe(this.parseMessage);
92 // TODO this should be checked out
93 componentDidUpdate() {
95 !this.state.loading &&
96 (this.state.communityForm.name ||
97 this.state.communityForm.title ||
98 this.state.communityForm.description)
100 window.onbeforeunload = () => true;
102 window.onbeforeunload = undefined;
106 componentWillUnmount() {
107 this.subscription.unsubscribe();
108 window.onbeforeunload = null;
116 !this.state.loading &&
117 (this.state.communityForm.name ||
118 this.state.communityForm.title ||
119 this.state.communityForm.description)
121 message={i18n.t("block_leaving")}
123 <form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
124 {!this.props.community_view && (
125 <div class="form-group row">
126 <label class="col-12 col-form-label" htmlFor="community-name">
129 class="pointer unselectable ml-2 text-muted"
130 data-tippy-content={i18n.t("name_explain")}
132 <Icon icon="help-circle" classes="icon-inline" />
140 value={this.state.communityForm.name}
141 onInput={linkEvent(this, this.handleCommunityNameChange)}
146 title={i18n.t("community_reqs")}
151 <div class="form-group row">
152 <label class="col-12 col-form-label" htmlFor="community-title">
153 {i18n.t("display_name")}
155 class="pointer unselectable ml-2 text-muted"
156 data-tippy-content={i18n.t("display_name_explain")}
158 <Icon icon="help-circle" classes="icon-inline" />
165 value={this.state.communityForm.title}
166 onInput={linkEvent(this, this.handleCommunityTitleChange)}
174 <div class="form-group">
175 <label>{i18n.t("icon")}</label>
177 uploadTitle={i18n.t("upload_icon")}
178 imageSrc={this.state.communityForm.icon}
179 onUpload={this.handleIconUpload}
180 onRemove={this.handleIconRemove}
184 <div class="form-group">
185 <label>{i18n.t("banner")}</label>
187 uploadTitle={i18n.t("upload_banner")}
188 imageSrc={this.state.communityForm.banner}
189 onUpload={this.handleBannerUpload}
190 onRemove={this.handleBannerRemove}
193 <div class="form-group row">
194 <label class="col-12 col-form-label" htmlFor={this.id}>
199 initialContent={this.state.communityForm.description}
200 onContentChange={this.handleCommunityDescriptionChange}
205 {this.props.enableNsfw && (
206 <div class="form-group row">
208 <div class="form-check">
210 class="form-check-input"
213 checked={this.state.communityForm.nsfw}
214 onChange={linkEvent(this, this.handleCommunityNsfwChange)}
216 <label class="form-check-label" htmlFor="community-nsfw">
223 <div class="form-group row">
227 class="btn btn-secondary mr-2"
228 disabled={this.state.loading}
230 {this.state.loading ? (
232 ) : this.props.community_view ? (
233 capitalizeFirstLetter(i18n.t("save"))
235 capitalizeFirstLetter(i18n.t("create"))
238 {this.props.community_view && (
241 class="btn btn-secondary"
242 onClick={linkEvent(this, this.handleCancel)}
254 handleCreateCommunitySubmit(i: CommunityForm, event: any) {
255 event.preventDefault();
256 i.state.loading = true;
257 if (i.props.community_view) {
258 let form: EditCommunity = {
259 ...i.state.communityForm,
260 community_id: i.props.community_view.community.id,
262 WebSocketService.Instance.send(wsClient.editCommunity(form));
264 WebSocketService.Instance.send(
265 wsClient.createCommunity(i.state.communityForm)
271 handleCommunityNameChange(i: CommunityForm, event: any) {
272 i.state.communityForm.name = event.target.value;
276 handleCommunityTitleChange(i: CommunityForm, event: any) {
277 i.state.communityForm.title = event.target.value;
281 handleCommunityDescriptionChange(val: string) {
282 this.state.communityForm.description = val;
283 this.setState(this.state);
286 handleCommunityNsfwChange(i: CommunityForm, event: any) {
287 i.state.communityForm.nsfw = event.target.checked;
291 handleCancel(i: CommunityForm) {
295 handleIconUpload(url: string) {
296 this.state.communityForm.icon = url;
297 this.setState(this.state);
301 this.state.communityForm.icon = "";
302 this.setState(this.state);
305 handleBannerUpload(url: string) {
306 this.state.communityForm.banner = url;
307 this.setState(this.state);
310 handleBannerRemove() {
311 this.state.communityForm.banner = "";
312 this.setState(this.state);
315 parseMessage(msg: any) {
316 let op = wsUserOp(msg);
318 toast(i18n.t(msg.error), "danger");
319 this.state.loading = false;
320 this.setState(this.state);
322 } else if (op == UserOperation.CreateCommunity) {
323 let data = wsJsonToRes<CommunityResponse>(msg).data;
324 this.state.loading = false;
325 this.props.onCreate(data.community_view);
326 } else if (op == UserOperation.EditCommunity) {
327 let data = wsJsonToRes<CommunityResponse>(msg).data;
328 this.state.loading = false;
329 this.props.onEdit(data.community_view);