1 import { Component, linkEvent } from "inferno";
2 import { Prompt } from "inferno-router";
3 import { CreateSite, EditSite, Site } from "lemmy-js-client";
4 import { i18n } from "../../i18next";
5 import { WebSocketService } from "../../services";
12 import { Spinner } from "../common/icon";
13 import { ImageUploadForm } from "../common/image-upload-form";
14 import { MarkdownTextArea } from "../common/markdown-textarea";
16 interface SiteFormProps {
17 site?: Site; // If a site is given, that means this is an edit
21 interface SiteFormState {
26 export class SiteForm extends Component<SiteFormProps, SiteFormState> {
27 private id = `site-form-${randomStr()}`;
28 private emptyState: SiteFormState = {
30 enable_downvotes: true,
31 open_registration: true,
41 constructor(props: any, context: any) {
42 super(props, context);
44 this.state = this.emptyState;
45 this.handleSiteSidebarChange = this.handleSiteSidebarChange.bind(this);
47 this.handleIconUpload = this.handleIconUpload.bind(this);
48 this.handleIconRemove = this.handleIconRemove.bind(this);
50 this.handleBannerUpload = this.handleBannerUpload.bind(this);
51 this.handleBannerRemove = this.handleBannerRemove.bind(this);
53 if (this.props.site) {
54 this.state.siteForm = {
55 name: this.props.site.name,
56 sidebar: this.props.site.sidebar,
57 description: this.props.site.description,
58 enable_downvotes: this.props.site.enable_downvotes,
59 open_registration: this.props.site.open_registration,
60 enable_nsfw: this.props.site.enable_nsfw,
61 community_creation_admin_only:
62 this.props.site.community_creation_admin_only,
63 icon: this.props.site.icon,
64 banner: this.props.site.banner,
70 // Necessary to stop the loading
71 componentWillReceiveProps() {
72 this.state.loading = false;
73 this.setState(this.state);
76 componentDidUpdate() {
78 !this.state.loading &&
80 (this.state.siteForm.name ||
81 this.state.siteForm.sidebar ||
82 this.state.siteForm.description)
84 window.onbeforeunload = () => true;
86 window.onbeforeunload = undefined;
90 componentWillUnmount() {
91 window.onbeforeunload = null;
99 !this.state.loading &&
101 (this.state.siteForm.name ||
102 this.state.siteForm.sidebar ||
103 this.state.siteForm.description)
105 message={i18n.t("block_leaving")}
107 <form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
110 ? capitalizeFirstLetter(i18n.t("save"))
111 : capitalizeFirstLetter(i18n.t("name"))
112 } ${i18n.t("your_site")}`}</h5>
113 <div class="form-group row">
114 <label class="col-12 col-form-label" htmlFor="create-site-name">
120 id="create-site-name"
122 value={this.state.siteForm.name}
123 onInput={linkEvent(this, this.handleSiteNameChange)}
130 <div class="form-group">
131 <label>{i18n.t("icon")}</label>
133 uploadTitle={i18n.t("upload_icon")}
134 imageSrc={this.state.siteForm.icon}
135 onUpload={this.handleIconUpload}
136 onRemove={this.handleIconRemove}
140 <div class="form-group">
141 <label>{i18n.t("banner")}</label>
143 uploadTitle={i18n.t("upload_banner")}
144 imageSrc={this.state.siteForm.banner}
145 onUpload={this.handleBannerUpload}
146 onRemove={this.handleBannerRemove}
149 <div class="form-group row">
150 <label class="col-12 col-form-label" htmlFor="site-desc">
151 {i18n.t("description")}
158 value={this.state.siteForm.description}
159 onInput={linkEvent(this, this.handleSiteDescChange)}
164 <div class="form-group row">
165 <label class="col-12 col-form-label" htmlFor={this.id}>
170 initialContent={this.state.siteForm.sidebar}
171 onContentChange={this.handleSiteSidebarChange}
172 hideNavigationWarnings
176 <div class="form-group row">
178 <div class="form-check">
180 class="form-check-input"
181 id="create-site-downvotes"
183 checked={this.state.siteForm.enable_downvotes}
186 this.handleSiteEnableDownvotesChange
189 <label class="form-check-label" htmlFor="create-site-downvotes">
190 {i18n.t("enable_downvotes")}
195 <div class="form-group row">
197 <div class="form-check">
199 class="form-check-input"
200 id="create-site-enable-nsfw"
202 checked={this.state.siteForm.enable_nsfw}
203 onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
206 class="form-check-label"
207 htmlFor="create-site-enable-nsfw"
209 {i18n.t("enable_nsfw")}
214 <div class="form-group row">
216 <div class="form-check">
218 class="form-check-input"
219 id="create-site-open-registration"
221 checked={this.state.siteForm.open_registration}
224 this.handleSiteOpenRegistrationChange
228 class="form-check-label"
229 htmlFor="create-site-open-registration"
231 {i18n.t("open_registration")}
236 <div class="form-group row">
238 <div class="form-check">
240 class="form-check-input"
241 id="create-site-community-creation-admin-only"
243 checked={this.state.siteForm.community_creation_admin_only}
246 this.handleSiteCommunityCreationAdminOnly
250 class="form-check-label"
251 htmlFor="create-site-community-creation-admin-only"
253 {i18n.t("community_creation_admin_only")}
258 <div class="form-group row">
262 class="btn btn-secondary mr-2"
263 disabled={this.state.loading}
265 {this.state.loading ? (
267 ) : this.props.site ? (
268 capitalizeFirstLetter(i18n.t("save"))
270 capitalizeFirstLetter(i18n.t("create"))
273 {this.props.site && (
276 class="btn btn-secondary"
277 onClick={linkEvent(this, this.handleCancel)}
289 handleCreateSiteSubmit(i: SiteForm, event: any) {
290 event.preventDefault();
291 i.state.loading = true;
293 WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm));
295 let form: CreateSite = {
296 name: i.state.siteForm.name || "My site",
299 WebSocketService.Instance.send(wsClient.createSite(form));
304 handleSiteNameChange(i: SiteForm, event: any) {
305 i.state.siteForm.name = event.target.value;
309 handleSiteSidebarChange(val: string) {
310 this.state.siteForm.sidebar = val;
311 this.setState(this.state);
314 handleSiteDescChange(i: SiteForm, event: any) {
315 i.state.siteForm.description = event.target.value;
319 handleSiteEnableNsfwChange(i: SiteForm, event: any) {
320 i.state.siteForm.enable_nsfw = event.target.checked;
324 handleSiteOpenRegistrationChange(i: SiteForm, event: any) {
325 i.state.siteForm.open_registration = event.target.checked;
329 handleSiteCommunityCreationAdminOnly(i: SiteForm, event: any) {
330 i.state.siteForm.community_creation_admin_only = event.target.checked;
334 handleSiteEnableDownvotesChange(i: SiteForm, event: any) {
335 i.state.siteForm.enable_downvotes = event.target.checked;
339 handleCancel(i: SiteForm) {
343 handleIconUpload(url: string) {
344 this.state.siteForm.icon = url;
345 this.setState(this.state);
349 this.state.siteForm.icon = "";
350 this.setState(this.state);
353 handleBannerUpload(url: string) {
354 this.state.siteForm.banner = url;
355 this.setState(this.state);
358 handleBannerRemove() {
359 this.state.siteForm.banner = "";
360 this.setState(this.state);